I'm trying to use this method to sort an integer array in ascending order. But my for loop runs through it only once.
public void sortArray()
{
boolean sorted = false;
while(sorted == false)
{
int temp;
for(int i = 0; i < inArray.length - 1; i++)
{
if(inArray[i] > inArray[i + 1])
{
temp = inArray[i];
inArray[i] = inArray[i + 1];
anArray[i + 1] = temp;
}
}
sorted = true;
}
}
I know it has to do with how I'm handling that boolean flag, but I'm not sure how to go about fixing it. Any suggestions would be appreciated. Thanks in advance.
There are multiple issues here:
while (sorted = false) sets sorted to false and then tests the resulting value false, meaning that you never enter the loop body at all (not once as per your question).
If you fix that, your code will only run the while loop body once (thus leaving the array not sorted yet), because you have sorted = true as an unconditional statement at the end of the loop body.
You need to have a flag that assumes the array is sorted, and then is cleared if you find evidence it wasn't, something like:
public void sortArray()
{
boolean sorted;
do
{
sorted = true; // Assume it's sorted
int temp;
for(int i = 0; i < inArray.length - 1; i++)
{
if(inArray[i] > inArray[i + 1])
{
temp = inArray[i];
inArray[i] = inArray[i + 1];
anArray[i + 1] = temp;
sorted = false; // We changed something, so assume we need to do another pass
}
}
}
while (!sorted);
}
Side note: This is just a style thing, but it's generally best to scope variables as narrowly as possible. There's no need for temp to be outside the for loop or even outside the if block, move it inside the if block
public void sortArray()
{
boolean sorted;
do
{
sorted = true; // Assume it's sorted
for(int i = 0; i < inArray.length - 1; i++)
{
if(inArray[i] > inArray[i + 1])
{
int temp = inArray[i];
inArray[i] = inArray[i + 1];
anArray[i + 1] = temp;
sorted = false; // We changed something, so assume we need to do another pass
}
}
}
while (!sorted);
}
You currently are setting your sorted to true allways at the end of the loop. While of course it should only be true if actually no reshuffling took place.
One way to archieve this would be to set sorted to true at the start of your while loop, and set it to false when you detect that the array is not yet sorted and you do the switching of elements:
public void sortArray()
{
boolean sorted = false;
while(!sorted)
{
sorted = true;
int temp;
for(int i = 0; i < inArray.length - 1; i++)
{
if(inArray[i] > inArray[i + 1])
{
sorted = false; // array is not yet sorted
temp = inArray[i];
inArray[i] = inArray[i + 1];
anArray[i + 1] = temp;
}
}
}
}
My method which contains no java collections
public class Main {
public static void main(String[] args) {
/** By Boris Elkin 21.09.2018 в 22.59 MSK You can input any digits, sorting was made without collections on purpose.
**/
int[] a1=new int[]{1,245623,3,3,3,3454,6,8123,234,123123,797897};
int[] a2=new int[]{234234, 33,4234,5,646456,9,78};
int[] a3;
a3= collide(a1, a2);
a3=sort(a3);
checkArray(a3);
}
public static int[] collide(int[]a, int[]b){
int breakpoint=0;
int size=a.length+b.length;
int[]c=new int[size];
for(int i=0;i<a.length;i++){
c[i]=a[i];
breakpoint=i;
}
for(int i=breakpoint+1,j=0;j<b.length;i++, j++){
c[i]=b[j];
}
return c;
}
public static int[] sort(int a[]){
boolean engine=true;
while(engine) {
for(int i=0;i<a.length;i++){
int temp, temp2;
if ((i + 1 < a.length) && (a[i] > a[i + 1])) {
temp = a[i];
temp2 = a[i + 1];
a[i + 1] = temp;
a[i] = temp2;
}
}
if(checkThreadLogistic(a)){
engine=false;
}
}
return a;
}
private static boolean checkThreadLogistic(int[] a) {
return checkCertainElement(a);
}
private static boolean checkCertainElement(int[] a) {
for(int i=0;i<a.length;i++){
if(i>1){
for(int j=a.length;j>i;j--){
if(j<a.length) if(a[i]>a[j])return false;
}
}
}
return true;
}
public static void checkArray(int[]array){
for (int anArray : array) {
System.out.println(anArray + "");
}
}
}
Related
On interview I was asked to write method with following contract:
boolean checkList(List<Long> list, long sum){...}
for example it has to return true for arguments:
({1,2,3,4,5,6}, 9) because 4+5 = 9
and it have to return false for arguments:
({0,10,30}, 11) because there are no combination of 2 elements with sum 11
I suggested code like this:
boolean checkList(List<Long> list, long expectedSum) {
if (list.size() < 2) {
return false;
}
for (int i = 0; i < list.size() - 1; i++) {
for (int k = i; k < list.size(); k++) {
if ((list.get(i) + list.get(k)) == expectedSum) {
return true;
}
}
}
return false;
}
But interviewer asked me to implement one more solution.
I am not able to create a better solution. Can you ?
Also give hashing a shot. There are more solutions to this problem located here.
// Java implementation using Hashing
import java.io.*;
import java.util.HashSet;
class PairSum
{
static void printpairs(int arr[],int sum)
{
HashSet<Integer> s = new HashSet<Integer>();
for (int i=0; i<arr.length; ++i)
{
int temp = sum-arr[i];
// checking for condition
if (temp>=0 && s.contains(temp))
{
System.out.println("Pair with given sum " +
sum + " is (" + arr[i] +
", "+temp+")");
}
s.add(arr[i]);
}
}
// Main to test the above function
public static void main (String[] args)
{
int A[] = {1, 4, 45, 6, 10, 8};
int n = 16;
printpairs(A, n);
}
}
Try this
public static boolean checklist(List<Long> list, long expectedSum) {
if(list.size() < 2) {
return false;
}
HashSet<Long> hs = new HashSet<Long>();
for(long i : list) {
hs.add(i);
}
for(int i=0; i< list.size(); i++) {
if(hs.contains(expectedSum - list.get(i))) {
return true;
}
}
return false;
}
One liner using java-8 :
public boolean checkList(List<Long> list, long expectedSum) {
Set<Long> hashSet = new HashSet<>(list);
return IntStream.range(0, list.size())
.anyMatch(i -> hashSet.contains(expectedSum - list.get(i)));
}
maybe look at each number and see if the total minus that number is in the list
so
boolean checkList(List<Long> list, long expectedSum) {
if (list.size() < 2) {
return false;
}
for (int i = 0; i < list.size(); i++) {
if(list.contains(expectedSum-list.get(i))){
return true;
}
}
return false;
}
Need to write an Algo to find Anagram of given string at a given index in lexicographically sorted order. For example:
Consider a String: ABC then all anagrams are in sorted order: ABC ACB
BAC BCA CAB CBA. So, for index 5 value is: CAB. Also, consider the case of duplicates like for AADFS anagram would be DFASA at index 32
To do this I have written Algo but I think there should be something less complex than this.
import java.util.*;
public class Anagram {
static class Word {
Character c;
int count;
Word(Character c, int count) {
this.c = c;
this.count = count;
}
}
public static void main(String[] args) {
System.out.println(findAnagram("aadfs", 32));
}
private static String findAnagram(String word, int index) {
// starting with 0 that's y.
index--;
char[] array = word.toCharArray();
List<Character> chars = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
chars.add(array[i]);
}
// Sort List
Collections.sort(chars);
// To maintain duplicates
List<Word> words = new ArrayList<>();
Character temp = chars.get(0);
int count = 1;
int total = chars.size();
for (int i = 1; i < chars.size(); i++) {
if (temp == chars.get(i)) {
count++;
} else {
words.add(new Word(temp, count));
count = 1;
temp = chars.get(i);
}
}
words.add(new Word(temp, count));
String anagram = "";
while (index > 0) {
Word selectedWord = null;
// find best index
int value = 0;
for (int i = 0; i < words.size(); i++) {
int com = combination(words, i, total);
if (index < value + com) {
index -= value;
if (words.get(i).count == 1) {
selectedWord = words.remove(i);
} else {
words.get(i).count--;
selectedWord = words.get(i);
}
break;
}
value += com;
}
anagram += selectedWord.c;
total--;
}
// put remaining in series
for (int i = 0; i < words.size(); i++) {
for (int j = 0; j < words.get(i).count; j++) {
anagram += words.get(i).c;
}
}
return anagram;
}
private static int combination(List<Word> words, int index, int total) {
int value = permutation(total - 1);
for (int i = 0; i < words.size(); i++) {
if (i == index) {
int v = words.get(i).count - 1;
if (v > 0) {
value /= permutation(v);
}
} else {
value /= permutation(words.get(i).count);
}
}
return value;
}
private static int permutation(int i) {
if (i == 1) {
return 1;
}
return i * permutation(i - 1);
}
}
Can someone help me with less complex logic.
I write the following code to solve your problem.
I assume that the given String is sorted.
The permutations(String prefix, char[] word, ArrayList permutations_list) function generates all possible permutations of the given string without duplicates and store them in a list named permutations_list. Thus, the word: permutations_list.get(index -1) is the desired output.
For example, assume that someone gives us the word "aab".
We have to solve this problem recursively:
Problem 1: permutations("","aab").
That means that we have to solve the problem:
Problem 2: permutations("a","ab").
String "ab" has only two letters, therefore the possible permutations are "ab" and "ba". Hence, we store in permutations_list the words "aab" and "aba".
Problem 2 has been solved. Now we go back to problem 1.
We swap the first "a" and the second "a" and we realize that these letters are the same. So we skip this case(we avoid duplicates).
Next, we swap the first "a" and "b". Now, the problem 1 has changed and we want to solve the new one:
Problem 3: permutations("","baa").
The next step is to solve the following problem:
Problem 4: permutations("b","aa").
String "aa" has only two same letters, therefore there is one possible permutation "aa". Hence, we store in permutations_list the word "baa"
Problem 4 has been solved. Finally, we go back to problem 3 and problem 3 has been solved. The final permutations_list contains "aab", "aba" and "baa".
Hence, findAnagram("aab", 2) returns the word "aba".
import java.util.ArrayList;
import java.util.Arrays;
public class AnagramProblem {
public static void main(String args[]) {
System.out.println(findAnagram("aadfs",32));
}
public static String findAnagram(String word, int index) {
ArrayList<String> permutations_list = new ArrayList<String>();
permutations("",word.toCharArray(), permutations_list);
return permutations_list.get(index - 1);
}
public static void permutations(String prefix, char[] word, ArrayList<String> permutations_list) {
boolean duplicate = false;
if (word.length==2 && word[0]!=word[1]) {
String permutation1 = prefix + String.valueOf(word[0]) + String.valueOf(word[1]);
permutations_list.add(permutation1);
String permutation2 = prefix + String.valueOf(word[1]) + String.valueOf(word[0]);
permutations_list.add(permutation2);
return;
}
else if (word.length==2 && word[0]==word[1]) {
String permutation = prefix + String.valueOf(word[0]) + String.valueOf(word[1]);
permutations_list.add(permutation);
return;
}
for (int i=0; i < word.length; i++) {
if (!duplicate) {
permutations(prefix + word[0], new String(word).substring(1,word.length).toCharArray(), permutations_list);
}
if (i < word.length - 1) {
char temp = word[0];
word[0] = word[i+1];
word[i+1] = temp;
}
if (i < word.length - 1 && word[0]==word[i+1]) duplicate = true;
else duplicate = false;
}
}
}
I think your problem will become a lot simpler if you considerate generating the anagrams in alphabetical order, so you don't have to sort them afterwards.
The following code (from Generating all permutations of a given string) generates all permutations of a String. The order of these permutations are given by the initial order of the input String. If you sort the String beforehand, the anagrams will thus be added in sorted order.
to prevent duplicates, you can simply maintain a Set of Strings you have already added. If this Set does not contain the anagram you're about to add, then you can safely add it to the list of anagrams.
Here is the code for the solution i described. I hope you find it to be simpler than your solution.
public class Anagrams {
private List<String> sortedAnagrams;
private Set<String> handledStrings;
public static void main(String args[]) {
Anagrams anagrams = new Anagrams();
List<String> list = anagrams.permutations(sort("AASDF"));
System.out.println(list.get(31));
}
public List<String> permutations(String str) {
handledStrings = new HashSet<String>();
sortedAnagrams = new ArrayList<String>();
permutation("", str);
return sortedAnagrams;
}
private void permutation(String prefix, String str) {
int n = str.length();
if (n == 0){
if(! handledStrings.contains(prefix)){
//System.out.println(prefix);
sortedAnagrams.add(prefix);
handledStrings.add(prefix);
}
}
else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
}
}
public static String sort(String str) {
char[] arr = str.toCharArray();
Arrays.sort(arr);
return new String(arr);
}
}
If you create a "next permutation" method which alters an array to its next lexicographical permutation, then your base logic could be to just invoke that method n-1 times in a loop.
There's a nice description with code that can be found here. Here's both the basic pseudocode and an example in Java adapted from that page.
/*
1. Find largest index i such that array[i − 1] < array[i].
(If no such i exists, then this is already the last permutation.)
2. Find largest index j such that j ≥ i and array[j] > array[i − 1].
3. Swap array[j] and array[i − 1].
4. Reverse the suffix starting at array[i].
*/
boolean nextPermutation(char[] array) {
int i = array.length - 1;
while (i > 0 && array[i - 1] >= array[i]) i--;
if (i <= 0) return false;
int j = array.length - 1;
while (array[j] <= array[i - 1]) j--;
char temp = array[i - 1];
array[i - 1] = array[j];
array[j] = temp;
j = array.length - 1;
while (i < j) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
return true;
}
I am stuck in the following program:
I have an input integer array which has only one non duplicate number, say {1,1,3,2,3}. The output should show the non duplicate element i.e. 2.
So far I did the following:
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
boolean flag = true;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
temp = arr[i];
for(int j=0;j<size;j++){
if(temp == arr[j]){
if(i != j)
//System.out.println("Match found for "+temp);
flag = false;
break;
}
}
}
return result;
}
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
Solution sol = new Solution();
System.out.println("SINGLE NUMBER : "+sol.singleNumber(a));
}
}
Restricting the solution in array is preferable. Avoid using collections,maps.
public class NonRepeatingElement {
public static void main(String[] args) {
int result =0;
int []arr={3,4,5,3,4,5,6};
for(int i:arr)
{
result ^=i;
}
System.out.println("Result is "+result);
}
}
Since this is almost certainly a learning exercise, and because you are very close to completing it right, here are the things that you need to change to make it work:
Move the declaration of flag inside the outer loop - the flag needs to be set to true every iteration of the outer loop, and it is not used anywhere outside the outer loop.
Check the flag when the inner loop completes - if the flag remains true, you have found a unique number; return it.
From Above here is the none duplicated example in Apple swift 2.0
func noneDuplicated(){
let arr = [1,4,3,7,3]
let size = arr.count
var temp = 0
for i in 0..<size{
var flag = true
temp = arr[i]
for j in 0..<size{
if(temp == arr[j]){
if(i != j){
flag = false
break
}
}
}
if(flag == true){
print(temp + " ,")
}
}
}
// output : 1 , 4 ,7
// this will print each none duplicated
/// for duplicate array
static void duplicateItem(int[] a){
/*
You can sort the array before you compare
*/
int temp =0;
for(int i=0; i<a.length;i++){
for(int j=0; j<a.length;j++){
if(a[i]<a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int count=0;
for(int j=0;j<a.length;j++) {
for(int k =j+1;k<a.length;k++) {
if(a[j] == a[k]) {
count++;
}
}
if(count==1){
System.out.println(a[j]);
}
count = 0;
}
}
/*
for array of non duplicate elements in array just change int k=j+1; to int k = 0; in for loop
*/
static void NonDuplicateItem(int[] a){
/*
You can sort the array before you compare
*/
int temp =0;
for(int i=0; i<a.length;i++){
for(int j=0; j<a.length;j++){
if(a[i]<a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int count=0;
for(int j=0;j<a.length;j++) {
for(int k =0 ;k<a.length;k++) {
if(a[j] == a[k]) {
count++;
}
}
if(count==1){
System.out.println(a[j]);
}
count = 0;
}
}
public class DuplicateItem {
public static void main (String []args){
int[] a = {1,1,1,2,2,3,6,5,3,6,7,8};
duplicateItem(a);
NonDuplicateItem(a);
}
/// for first non repeating element in array ///
static void FirstNonDuplicateItem(int[] a){
/*
You can sort the array before you compare
*/
int temp =0;
for(int i=0; i<a.length;i++){
for(int j=0; j<a.length;j++){
if(a[i]<a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int count=0;
for(int j=0;j<a.length;j++) {
//int k;
for(int k =0; k<a.length;k++) {
if(a[j] == a[k]) {
count++;
}
}
if(count==1){
System.out.println(a[j]);
break;
}
count = 0;
}
}
public class NonDuplicateItem {
public static void main (String []args){
int[] a = {1,1,1,2,2,3,6,5,3,6,7,8};
FirstNonDuplicateItem(a);
}
I have a unique answer, it basically takes the current number that you have in the outer for loop for the array and times it by itself (basically the number to the power of 2). Then it goes through and every time it sees the number isn't equal to double itself test if its at the end of the array for the inner for loop, it is then a unique number, where as if it ever find a number equal to itself it then skips to the end of the inner for loop since we already know after one the number is not unique.
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
int temp2 = 0;
int temp3 = 0;
boolean flag = true;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
temp = arr[i];
temp2 = temp*temp;
for(int j=0;j<size;j++){
temp3 = temp*arr[j];
if(temp2==temp3 && i!=j)
j=arr.length
if(temp2 != temp3 && j==arr.length){
//System.out.println("Match found for "+temp);
flag = false;
result = temp;
break;
}
}
}
return result;
}
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
Solution sol = new Solution();
System.out.println("SINGLE NUMBER : "+sol.singleNumber(a));
}
}
not tested but should work
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
boolean flag = true;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
temp = arr[i];
int count=0;
for(int j=0;j<size;j++){
if(temp == arr[j]){
count++;
}
}
if (count==1){
result=temp;
break;
}
}
return result;
}
Try:
public class Answer{
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
int[] b =new int[a.length];
//instead of a.length initialize it to maximum element value in a; to avoid
//ArrayIndexOutOfBoundsException
for(int i=0;i<a.length;i++){
int x=a[i];
b[x]++;
}
for(int i=0;i<b.length;i++){
if(b[i]==1){
System.out.println(i); // outputs 2
break;
}
}
}
}
PS: I'm really new to java i usually code in C.
Thanks #dasblinkenlight...followed your method
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
boolean flag = true;
temp = arr[i];
for(int j=0;j<size;j++){
if(temp == arr[j]){
if(i != j){
// System.out.println("Match found for "+temp);
flag = false;
break;
}
}
}
if(flag == true)
result = temp;
}
return result;
}
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
Solution sol = new Solution();
System.out.println("SINGLE NUMBER : "+sol.singleNumber(a));
}
}
One disastrous mistake was not enclosing the content of if(i != j) inside braces. Thanks all for your answers.
If you are coding for learning then you can solve it with still more efficiently.
Sort the given array using merge sort of Quick Sort.
Running time will be nlogn.
The idea is to use Binary Search.
Till required element found All elements have first occurrence at even index (0, 2, ..) and next occurrence at odd index (1, 3, …).
After the required element have first occurrence at odd index and next occurrence at even index.
Using above observation you can solve :
a) Find the middle index, say ‘mid’.
b) If ‘mid’ is even, then compare arr[mid] and arr[mid + 1]. If both are same, then the required element after ‘mid’ else before mid.
c) If ‘mid’ is odd, then compare arr[mid] and arr[mid – 1]. If both are same, then the required element after ‘mid’ else before mid.
Another simple way to do so..
public static void main(String[] art) {
int a[] = { 11, 2, 3, 1,1, 6, 2, 5, 8, 3, 2, 11, 8, 4, 6 ,5};
Arrays.sort(a);
System.out.println(Arrays.toString(a));
for (int j = 0; j < a.length; j++) {
if(j==0) {
if(a[j]!=a[j+1]) {
System.out.println("The unique number is :"+a[j]);
}
}else
if(j==a.length-1) {
if(a[j]!=a[j-1]) {
System.out.println("The unique number is :"+a[j]);
}
}else
if(a[j]!=a[j+1] && a[j]!=a[j-1]) {
System.out.println("The unique number is :"+a[j]);
}
}
}
Happy Coding..
Using multiple loops the time complexity is O(n^2), So the effective way to resolve this using HashMap which in the time complexity of O(n). Please find my answer below,
`public static int nonRepeatedNumber(int[] A) {
Map<Integer, Integer> countMap = new HashMap<>();
int result = -1;
for (int i : A) {
if (!countMap.containsKey(i)) {
countMap.put(i, 1);
} else {
countMap.put(i, countMap.get(i) + 1);
}
}
Optional<Entry<Integer, Integer>> optionalEntry = countMap.entrySet().stream()
.filter(e -> e.getValue() == 1).findFirst();
return optionalEntry.isPresent() ? optionalEntry.get().getKey() : -1;
}
}`
I'm planning on a sorting marathon where I'll look up pseudo-code for common sorting algorithms and try implement them in Java.
The first one I'm trying is bubblesort. I wrote the simplest form which appears to work fine:
package bubblesort;
public class Sort {
private static void swapElements(int[] array, int index1, int index2) {
int holder = array[index1];
array[index1] = array[index2];
array[index2] = holder;
}
public static void ascending(int[] array) {
boolean sorted = false;
while(!sorted) {
sorted = true; //if no elements are swapped, 'sorted' remains equal to true and the while-loop ends.
for(int i = 0; i < array.length - 1; i++) {
if(array[i] > array[i + 1]) {
swapElements(array, i, i + 1);
sorted = false;
}
}
}
}
}
However, since the highest value is brought to the last element each time the for-loop gets executed, I tried to improve it by leaving out elements at the end, introducing a new variable that counts how many times the whole array is checked:
package bubblesort;
public class Sort {
private static void swapElements(int[] array, int index1, int index2) {
int holder = array[index1];
array[index1] = array[index2];
array[index2] = holder;
}
public static void ascending(int[] array) {
int timesLooped = 0;
boolean sorted = false;
while(!sorted) {
sorted = true;
for(int i = 0; i < array.length - timesLooped - 1; i++) {
if(array[i] > array[i + 1]) {
swapElements(array, i, i + 1);
sorted = false;
}
timesLooped++;
}
}
}
}
This time the sort fails; only some of the elements in the array get sorted, others don't.
So my question is: What is wrong with the way I introduced the 'timesLooped' variable that attempts to avoid making unnecessary comparisons?
timesLopped++ shall be outside the for loop:
public static void ascending(int[] array) {
int timesLooped = 0;
boolean sorted = false;
while(!sorted) {
sorted = true;
for(int i = 0; i < array.length - timesLooped - 1; i++) {
if(array[i] > array[i + 1]) {
swapElements(array, i, i + 1);
sorted = false;
}
}
timesLooped++;
}
}
The purpose of this program is to find the kth smallest element in an array without sorting the array using a recursive and nonrecursive decrease and conquer type method.
I was hoping someone could look over my code and try to help me with my array out of bounds error(s).
The method that is throwing these errors is the recursive selection the non recursive selection works fine.
My driver is also attached and everything should compile if you want to test my code.
public class KthSmallest
{
private int counter;
private int term;
private int[] A;
int SelectionNonRecursive(int A[], int kthSmallest, int sizeOfA)
{
this.A = A;
if(kthSmallest == 1 || kthSmallest == sizeOfA)
{
return (LinearSearch(kthSmallest, sizeOfA));
}
else
{
for(int i = 0; i<sizeOfA; i++)
{
counter = 0;
for(int j = 0; j<sizeOfA; j++)
{
if(A[i] < A[j])
{
counter++;
}
}
if((sizeOfA - counter) == kthSmallest)
{
return A[i];
}
}
}
return 0;
}
int SelectionRecursive(int A[], int kthSmallest, int sizeOfA)
{
this.A = A;
return Selection_R(0, sizeOfA - 1, kthSmallest);
}
int Selection_R(int l, int r, int kthSmallest)
{
if(l<r)
{
if(kthSmallest == 1 || kthSmallest == A.length)
{
return (LinearSearch(kthSmallest, A.length));
}
else
{
int s = LomutoPartition(l, r);
if(s == kthSmallest - 1)
{
return A[s];
}
else if(s > (A[0] + kthSmallest - 1))
{
Selection_R(l, s-1, kthSmallest);
}
else
{
Selection_R(s+1, r, kthSmallest);
}
}
}
return 0;
}
int LomutoPartition(int l, int r)
{
int pivot = A[l];
int s = l;
for(int i = l+1; i<r; i++)
{
if(A[i] < pivot)
{
s += 1;
swap(A[s], A[i]);
}
}
swap(A[l], A[s]);
return s;
}
public void swap(int i, int j)
{
int holder = A[i];
A[i] = A[j];
A[j] = holder;
}
int LinearSearch(int kthSmallest, int sizeOfA)
{
term = A[0];
for(int i=1; i<sizeOfA; i++)
{
if(kthSmallest == 1)
{
if(term > A[i])
{
term = A[i];
}
}
else
{
if(term < A[i])
{
term = A[i];
}
}
}
return term;
}
}
public class KthDriver
{
public static void main(String[] args)
{
KthSmallest k1 = new KthSmallest();
int[] array = {7,1,5,9,3};
System.out.print(k1.SelectionRecursive(array, 3, array.length));
}
}
Inside your LomutoPartition method, you are passing the array elements in your swap method: -
swap(A[s], A[i]); // Inside for loop
and
swap(A[l], A[s]); // Outside for loop
And your swap method considers them as indices: -
public void swap(int i, int j) <-- // `i` and `j` are elements A[s] and A[i]
{
int holder = A[i]; <-- // You are accessing them as indices(A[i] -> A[A[s]])
A[i] = A[j];
A[j] = holder;
}
That is why you are getting that exception. Because, if any element in array is greater than size, it will blast out.
You should change your invocation to: -
swap(s, i); // Inside for loop
and
swap(l, s); // Outside for loop
respectively. And leave your method as it is.
Note that, you should pass array indices, and not array elements. If you pass array elements, then the swapping in the method will not be reflected in your array. Because, your method will have its own copy of your elements.