Find the k smallest integer in an array - java

Here is my code, it works for finding 1-7 smallest integers, but 8 and 9. It returns null when I find 8 smallest integer in the array. Can anyone help me where is the problem? I am using quicksort here.
Thanks very much!
update: I have figured out the problem, which is the array in the main function. After I change to the following look,
int[] arr = {2, 3, 1, 7, 5, 6, 20, 8, 4, 9};
and
if(front>=end) return input;
It works now!
import java.util.Arrays;
import java.io.*;
class quicksort{
public static void main(String[] args){
int[] arr = new int[9];
arr[0] = 7;
arr[1] = 2;
arr[2] = 4;
arr[3] = 8;
arr[4] = 3;
arr[5] = 5;
arr[6] = 1;
arr[7] = 0;
arr[8] = 10;
System.out.println((Arrays.toString(findKSamllest(arr,8))));
}
public static int partition(int[] input, int front, int end){
int pivot = input[front];
while(front < end){
while(input[front]<pivot)
front++;
while(input[end]>pivot)
end--;
swap(input,front,end);
}
return front;
}
public static void swap(int[] input, int s, int l){
int temp = input[s];
input[s] = input[l];
input[l] = temp;
}
public static int[] findK(int[] input, int front, int end, int k){
if(front>=end) return null;
int pivot = partition(input,front,end);
//System.out.println(pivot);
if(k==pivot){
return Arrays.copyOfRange(input,0,pivot);
}
else {
if(k<pivot)
return findK(input,front,pivot,k);
return findK(input,pivot+1,end,k);
}
}
public static int[] findKSamllest(int[] input, int k){
return findK(input, 0, input.length-1, k);
}
}

Change
if(front >= end) return null;
to
if(front > end) return null;

Stand on the shoulders of giants and use the libraries that are already available:
Arrays.sort(myArray);
int[] returnArray = new int(NUM_ITEMS_TO_RETURN);
for (int i=0; i < NUM_ITEMS_TO_RETURN; i++)
{
returnArray[i] = myArray[i];
}
return returnArray;
Obviously you have to do some error checking, for example that the initial array is larger or equal to the number of items you want returned, but that's trivial.

You could save you a bit time and impress your teacher with the fancy new Java 8 API.
It provides streams and useful functions to solve this in one (long) line or 5, if it should be readable ;-)
final List<Integer> sortedKList = Arrays.asList(7, 2, 4, 8, 3, 5, 1, 0, 10)
.stream()
.sorted()
.limit(7)
.collect(Collectors.toList());
You can then review your result with:
sortedKList.forEach(System.out::println);

Related

Java - Implementing QuickSort [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I'm learning datastructures and algorithms. So I have tried implementing the quick sort alogorithm.
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 10, 16, 8, 12, 15, 6, 3, 9, 5 };
quickSort(0, arr.length - 1, arr);
}
public static void quickSort(int start, int end, int[] arr) {
if (start < end) {
int partitionIndex = partition(start, end, arr);
quickSort(start, partitionIndex - 1, arr);
quickSort(partitionIndex+1, end, arr); // When passing partitionIndex+1 in the swap method it throws index out of bound exception
System.out.println(Arrays.toString(arr));
}
}
public static int partition(int start, int end, int[] arr) {
int pivot = arr[end];
int pIndex = start;
for (int i = 0; i < end - 1; i++) {
if (arr[i] <= pivot) {
swap(i, pIndex, arr);
pIndex++;
}
}
swap(pIndex, end, arr);
return pIndex;
}
private static void swap(int i, int index, int[] arr) {
int temp = arr[i];
arr[i] = arr[index]; // index out of bound exception is thrown
arr[index] = temp;
}
When doing the recursive call quickSort(partitionIndex+1, end, arr); and in the swap method it is throwing index out of bound exception. Because there is no such index to retrieve/store the value.
Can any one please help me to resolve this issue?
I assume you tried to implement the Lomuto partition scheme from Wikipedia. If that's the case you have 2 errors in your code, both in the for loop of the partition method:
start index:
You algorithm starts every time at 0. That is causing the IndexOutOfBoundsException, because it swaps pIndex which is array.length at the end. If you fix this, the exception will be gone, but your sorted result will be [3, 5, 8, 10, 12, 15, 6, 16, 9], which is obviously not perfectly sorted.
end condition:
The error here is, that the last iteration is missing every time, because your end condition is i < end - 1 change that to i < end or i <= end - 1 and you should get a perfect result:
[3, 5, 6, 8, 9, 10, 12, 15, 16]
For completion here is the fixed partition method and your quickSort method:
public static void quickSort(int start, int end, int[] arr) {
if (start < end) {
int partitionIndex = partition(start, end, arr);
quickSort(start, partitionIndex - 1, arr);
quickSort(partitionIndex + 1, end, arr);
}
}
public static int partition(int start, int end, int[] arr) {
int pivot = arr[end];
int pIndex = start;
for (int i = start; i < end; i++) {
if (arr[i] < pivot) {
swap(pIndex, i, arr);
pIndex++;
}
}
swap(pIndex, end, arr);
return pIndex;
}

Binary Search implementation via java

Please see the below java source code for binary search implementation
public class Main {
public static void main(String[] args) {
int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int y = binarySearch(x, 11);
System.out.println(y);
}
public static int binarySearch(int[] arr, int value) {
int searchedIndex = -1;
int first = 0;
int last = arr.length - 1;
int mid;
while (first <= last) {
mid = (first + last) / 2;
if (arr[mid] == value) {
searchedIndex = mid;
break;
} else {
if (value < arr[mid]) {
last = mid - 1;
} else {
first = mid + 1;
}
}
}
return searchedIndex;
}
}
int last = arr.length - 1 is -1 compulsory or not. I feel that code works fine either last = arr.length - 1. If its compulsory please explain why.
Arrays already have a method binarySearch you can just use :
int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int r = Arrays.binarySearch(x, 11);
The -1 is needed for one very specific case: when you search for a value that is larger than the largest value in the array. For example, calling your function with
int y = binarySearch(x, 50);
will throw an ArrayOutOfBounds exception. That's because mid will eventually be equal to last, and without the -1, last is past the end of the array.

Java function to calculate permutations without repeats

I have an ArrayList and I want to find all of the combinations of a given size without repeats inside it with a single function (built in or not). For example:
ArrayList<Integer> numbers = Array.asList(96, 32, 65, 21);
getCombinationsWithoutRepeats(numbers, 2);
Output:
>>> [[96, 32], [96, 65], [96, 21], [32, 65], [32, 21], [65, 21]]
How would I create this function or is there an inbuilt function that does this?
Here is a sample solution, using backtracking. It will generate you all possible permutations of size K and store them in lists field.
List<List<Integer>> lists = new ArrayList<List<Integer>>();
void permutate(int[] arr, int k) {
internalPermutate(arr, k, 0, 0);
}
void internalPermutate(int[] arr, int k, int step, int index) {
if (step == k) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < k; i++) {
list.add(arr[i]);
}
lists.add(list);
}
for (int i = step + index; i < arr.length; i++) {
swap(arr, step, i);
internalPermutate(arr, k, step + 1, i);
swap(arr, step, i);
}
}
private void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
public static void main(String[] args) {
new SomeClass().permutate(new int[] { 1, 2, 3, 4 }, 2);
System.out.println(lists);
}
This solution doesn't deal with situation when we have the same elements in array, but you can just exclude them before permutation.

A recursive algorithm to find every possible sum given an integer array?

So given an array for example [3, 5, 7, 2] I want to use recursion to give me all the possible combinations of sums, for example: 3, 5, 7, 2, 8(3+5),10(3+7),5(3+5)... 15(3+5+7) etc. I'm not exactly sure how to go about this using java.
You have two choice with each number in the array.
Use the number
Don't use the number
void foo(int[] array, int start, int sum) {
if(array.length == start) return;
int val = sum + array[start];
//print val;
foo(array, start + 1, val); //use the number
foo(array, start + 1, sum); //don't use the number
}
the initial call is foo(a, 0, 0)
An recursive algorithm for this could work as follows:
All the sums for a list equals the union of:
The first number plus the sums of the sublist without the first number
The sums of the sublist without the first number
Eventually your recursive call will hit the stopping condition of an empty list, which has only one sum(zero)
Here's one way of doing it in pseudo code:
getAllPossibleSums(list)
if(list.length == 1)
return list[0];
otherSums = getAllPossibleSums(list[1:end])
return union(
otherSums, list[0] + otherSums);
public static void main(String[] args) {
findAllSums(new int[] {3, 5, 7, 2}, 0, 0);
}
static void findAllSums(int[] arrayOfNumbers, int index, int sum) {
if (index == arrayOfNumbers.length) {
System.out.println(sum);
return;
}
findAllSums(arrayOfNumbers, index + 1, sum + arrayOfNumbers[index]);
findAllSums(arrayOfNumbers, index + 1, sum);
}
You have two branches, one in which you add the current number and another in which you don't.
public static void main(String[] args) {
int [] A = {3, 5, 7, 2};
int summation = recursiveSum(A, 0, A.length-1);
System.out.println(summation);
}
static int recursiveSum(int[] Array, int p, int q) {
int mid = (p+q)/2; //Base case
if (p>q) return 0; //Base case
else if (p==q) return Array[p];
**else
return recursiveSum(Array, p, mid) + recursiveSum(Array, mid + 1, q);**
}
Simplest way ever:
private int noOfSet;
Add below method:
private void checkSum() {
List<Integer> input = new ArrayList<>();
input.add(9);
input.add(8);
input.add(10);
input.add(4);
input.add(5);
input.add(7);
input.add(3);
int targetSum = 15;
checkSumRecursive(input, targetSum, new ArrayList<Integer>());
}
private void checkSumRecursive(List<Integer> remaining, int targetSum, List<Integer> listToSum) {
// Sum up partial
int sum = 0;
for (int x : listToSum) {
sum += x;
}
//Check if sum matched with potential
if (sum == targetSum) {
noOfSet++;
Log.i("Set Count", noOfSet + "");
for (int value : listToSum) {
Log.i("Value", value + "");
}
}
//Check sum passed
if (sum >= targetSum)
return;
//Iterate each input character
for (int i = 0; i < remaining.size(); i++) {
// Build list of remaining items to iterate
List<Integer> newRemaining = new ArrayList<>();
for (int j = i + 1; j < remaining.size(); j++)
newRemaining.add(remaining.get(j));
// Update partial list
List<Integer> newListToSum = new ArrayList<>(listToSum);
int currentItem = remaining.get(i);
newListToSum.add(currentItem);
checkSumRecursive(newRemaining, targetSum, newListToSum);
}
}
Hope this will help you.

Array even & odd sorting

I have an array where I have some numbers. Now I want to sort even numbers in a separate array and odd numbers in a separate. Is there any API to do that? I tried like this
int[] array_sort={5,12,3,21,8,7,19,102,201};
int [] even_sort;
int i;
for(i=0;i<8;i++)
{
if(array_sort[i]%2==0)
{
even_sort=Arrays.sort(array_sort[i]);//error in sort
System.out.println(even_sort);
}
}
Plain and simple.
int[] array_sort = {5, 12, 3, 21, 8, 7, 19, 102, 201 };
List<Integer> odd = new ArrayList<Integer>();
List<Integer> even = new ArrayList<Integer>();
for (int i : array_sort) {
if ((i & 1) == 1) {
odd.add(i);
} else {
even.add(i);
}
}
Collections.sort(odd);
Collections.sort(even);
System.out.println("Odd:" + odd);
System.out.println("Even:" + even);
Your question as stated doesn't make sense, and neither does the code. So I'm guessing that you want to separate the elements of an array into two arrays, one containing odds and the other evens. If so, do it like this:
int[] input = {5, 12, 3, 21, 8, 7, 19, 102, 201};
List<Integer> evens = new ArrayList<Integer>();
List<Integer> odds = new ArrayList<Integer>();
for (int i : input) {
if (i % 2 == 0) {
evens.add(i);
} else {
odds.add(i);
}
}
You can then convert a list of Integer to a sorted array if int as follows:
List<Integer> list ...
int[] array = new int[list.size()];
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}
Arrays.sort(array);
or if a sorted List<Integer> is what you need, just do this:
Collections.sort(list);
It's simple to do this using Guava.
Use Ints.asList to create a List<Integer> live view of an int[]
Define a Function<Integer,Boolean> isOdd
Use Ordering that compares onResultOf(isOdd), naturally (i.e. false first, then true)
If necessary, compound that with an Ordering.natural()
Here's the snippet:
int[] nums = {5,12,3,21,8,7,19,102,201};
Function<Integer,Boolean> isOdd = new Function<Integer,Boolean>() {
#Override
public Boolean apply(Integer i) {
return (i & 1) == 1;
}
};
Collections.sort(
Ints.asList(nums),
Ordering.natural().onResultOf(isOdd)
.compound(Ordering.natural())
);
System.out.println(Arrays.toString(nums));
// [8, 12, 102, 3, 5, 7, 19, 21, 201]
Note that all the even numbers show up first, then all the odd numbers. Within each group, the numbers are sorted naturally.
External links
polygenelubricants.com - Writing more elegant comparison logic with Guava's Ordering
There are some things to know first :
You must initialize an array before using it. For example int[] even_sort = new int[3];
In java arrays have a static size. That means that you won't be able to add as many elements as you want. You have to choose a size before. You should take a look at Java Collections, it's a good way to get rid of this "rule" the java way.
The Arrays.sort() method apply on arrays only. Here array_sort[i] is an int
Arrays.sort() sorts an array but doesn't return anything.
If you really want to use arrays (but you shouldn't) you can do something like this to resize one :
int[] even_sort = new int[3]{1, 2, 3};
int[] temp = new int[4];
System.arraycopy(even_sort, 0, temp, 0, even_sort.length);
even_sort = temp;
even_sort[3] = 4;
Another way would be creating an utility method which uses reflection to create the new array :
import java.lang.reflect.Array;
public Object resizeArray(Object originalArray, int newSize){
int originalSize = Array.getLength(originalArray);
Class arrayType = originalArray.getClass().getComponentType();
Object newArray = Array.newInstance(arrayType, newSize);
System.arraycopy(originalArray, 0, newArray, 0, Math.min(originalSize, newSize));
return newArray;
}
So if you still want to use array for some reasons (but you still shouldn't) here is a code to filter, resize and sort your array.
int[] arrayToFilterAndSort = {5, 12, 3, 21, 8, 7, 19, 102, 201};
int[] sortedEvens = new int[0];
for(int current : arrayToFilterAndSort){
if((current & 1) == 1){
sortedEvens = resizeArray(sortedEvens, sortedEvens.length + 1);
sortedEvens[sortedEvens.length - 1] = current;
}
}
Arrays.sort(sortedEvens);
Resources :
oracle.com - Arrays tutorial
oracle.com - Collections tutorial
javadoc - Arrays.sort()
package com.java.util.collection;
import java.util.Arrays;
/**
* Given n random numbers. Move all even numbers on left hand side and odd numbers on right hand side and
* then sort the even numbers in increasing order and odd numbers in decreasing order For example,
* i/p : 3 6 9 2 4 10 34 21 5
* o/p: 2 4 6 10 34 3 5 9 21
* #author vsinha
*
*/
public class EvenOddSorting {
public static void eventOddSort(int[] arr) {
int i =0;
int j =arr.length-1;
while(i<j) {
if(isEven(arr[i]) && isOdd(arr[j])) {
i++;
j--;
} else if(!isEven(arr[i]) && !isOdd(arr[j])) {
swap(i,j,arr);
} else if(isEven(arr[i])){
i++;
} else{
j--;
}
}
display(arr);
// even number sorting
Arrays.sort(arr,0,i);
Arrays.sort(arr,i,arr.length);
// odd number sorting
display(arr);
}
public static void display(int[] arr) {
System.out.println("\n");
for(int val:arr){
System.out.print(val +" ");
}
}
private static void swap(int pos1, int pos2, int[] arr) {
int temp = arr[pos1];
arr[pos1]= arr[pos2];
arr[pos2]= temp;
}
public static boolean isOdd(int i) {
return (i & 1) != 0;
}
public static boolean isEven(int i) {
return (i & 1) == 0;
}
public static void main(String[] args) {
int arr[]={3, 6, 9 ,2, 4, 10, 34, 21, 5};
eventOddSort(arr);
}
}
int arr[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
cout << "The Even no are : \n";
for (int i = 1; i <= 10; i++) // for start for only i....(even nos)
{
if (i % 2 == 0)
{
cout << i;
cout << " ";
}
}
cout << "\nThe Odd no are : \n";
for (int j = 1; j <= 10; j++) // for start for only j....(odd nos)
{
if (j % 2 != 0)
{
cout << j;
cout << " ";
}`enter code here`
}
package srikanth dukuntla;
public class ArrangingArray {
public static void main(String[] args) {
int j=0;
int []array={1,2,3,5,4,55,32,0};
System.out.println(array.length);
int n=array.length/2;
for (int i=0; i<array.length; i++){
if(array[i]%2!=0){
j=1;
int temp=array[array.length-j];
if(temp % 2!=0){
while((array[array.length-(j+1)]%2!=0) && (array.length-(j+1)>n)){
j++;
}
int temp2=array[array.length-(j+1)];
array[array.length-(j+1)] =array[i];
array[i]=temp2;
}else // inner if
{
array[array.length-j] =array[i];
array[i]=temp;
}
}else //main if
{
//nothing needed
}
}
for(int k=0;k<array.length;k++) {
System.out.print(" "+ array[k]);
}
}
}
List < Integer > odd = new ArrayList < Integer > ();
List < Integer > even = new ArrayList < Integer > ();
int a [] = {0,2,3,98,1,6546,45323,1134564};
int i;
for (i = 0; i < a.length; i++) {
if (a[i] % 2 == 0) {
even.add(a[i]);
} else {
odd.add(a[i]);
}
}
System.out.print("Even: " + even + "\n");
System.out.print("Uneven: " + odd + "\n");
}
}

Categories

Resources