having issues with a quicksort method - java

So i am doing a challenge located at https://www.hackerrank.com/challenges/quicksort2 and im having trouble wrapping my head around doing this the way they want. They are asking for the program to do a quicksort using subArrays and then put those sub arrays together at the end to come up with the result. Here is the challenge and i will have my code below. needless to say i don't have it working. All the code was provided and the challenge is to write the partition method
Print Sub-Arrays
In this challenge, print your array every time your partitioning method finished, i.e. print every sorted sub-array The first element in a sub-array should be used as a pivot. Partition the left side before partitioning the right side. The pivot should not be added to either side. Instead, put it back in the middle when combining the sub-arrays together.
Input Format
There will be two lines of input:
n - the size of the array
ar - the n numbers of the array
Output Format
Print every partitioned sub-array on a new line.
Constraints
1<=n<=1000
-1000<=x<= 1000 , x ∈ ar
There are no duplicate numbers.
Sample Input
7
5 8 1 3 7 9 2
Sample Output
2 3
1 2 3
7 8 9
1 2 3 5 7 8 9
Code
import java.util.*;
public class Solution {
static int[] result;
static void partition(int[] ar) {
int p = 0;
int s = 0;
int l = 0;
int small[] = new int[ar.length];
int pivot[] = new int[ar.length];
int large[] = new int[ar.length];
for(int i = 0; i < ar.length; i++){
if(i == 0 || ar[i]==pivot[0]){
pivot[p] = ar[i];
p++;
}
else if(ar[i]>pivot[0]){
large[l] = ar[i];
l++;
}
else if(ar[i]<pivot[0]){
small[s] = ar[i];
s++;
}
}
if(s>2){
int[] smallA = new int[s];
for(int i = 0; i < s; i ++){
smallA[i] = small[i];
}
partition(smallA);
}
if(l>2){
int[] largeA = new int[l];
for(int i = 0; i < l; i ++){
largeA[i] = large[i];
}
partition(largeA);
}
}
static void printArray(int[] ar) {
for(int n: ar){
System.out.print(n+" ");
}
System.out.println("");
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] ar = new int[n];
result = new int[n];
for(int i=0;i<n;i++){
ar[i]=in.nextInt();
}
partition(ar);
}
}
i have to use this format, i can edit the partition method but the rest stays per rules of the challenge

I haven't checked your code, but this seems to work. It's easier to make it with List
import java.util.*;
public class quickSorter
{
public quickSorter()
{
}
public List<Integer> partition(List<Integer> list){
int pivot = list.get(0);
List<Integer> result;
List<Integer> leftSide = new ArrayList<>();
List<Integer> rightSide = new ArrayList<>();
for (int i=0;i<list.size();i++){
if (list.get(i)<pivot){
leftSide.add(list.get(i));
}
else if (list.get(i)>pivot){
rightSide.add(list.get(i));
}
}
if (leftSide.size()>1){
result = this.partition(leftSide);
leftSide=result;
}
if (rightSide.size()>1){
result = this.partition(rightSide);
rightSide=result;
}
List<Integer> combined = new ArrayList<>();
combined.addAll(leftSide);
combined.add(pivot);
combined.addAll(rightSide);
//print out
for (int j:combined){
System.out.print(j+" ");
}
System.out.println();
return combined;
}
public static void main(String[] a){
quickSorter qs = new quickSorter();
List<Integer> list = new ArrayList<>();
System.out.println();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int i=0;i<n;i++){
list.add(in.nextInt());
}
System.out.println();
List<Integer> sorted = qs.partition(list);
}
}

Related

Counting Sort implementation

Hello I am having difficulty implementing a counting sort method in java. I believe the problem comes from the last two loops I have in the method. I am getting an ArrayIndexOutOfBounds exception : 8. I believe this comes from my second to last for loop when at index 5 the value is 8 but I am not sure how to resolve this. Any help is appreciated. Thank you!
In my code k is the highest value in the input array.
Code:
public static void main(String[] args) {
int [] arrayOne = {0,1,1,3,4,5,3,0};
int [] output = Arrays.copyOf(arrayOne, arrayOne.length);
System.out.println(Arrays.toString(arrayOne));
countingSort(arrayOne, output, 5);
System.out.println(Arrays.toString(output));
}
public static void countingSort(int[] input, int[] output , int k){
int [] temp = Arrays.copyOf(input, k+1);
for (int i = 0; i <= k; i++){
temp[i] = 0;
}
for (int j = 0; j <= input.length - 1; j++){
temp[input[j]] = temp[input[j]] + 1;
}
for (int i = 1; i <= k; i++){
temp[i] = temp[i] + temp[i-1];
}
for (int j = input.length; j >= 1; j--){
output[temp[input[j]]] = input[j];
temp[input[j]] = temp[input[j]] - 1;
}
}
The problem is in the first loop because the array temp lenght is 6 and you are doing 7 interations in there.
So at the end of the for it is trying to do temp[6]=0 and the last position of your array is temp[5].
To fix this change your first loop to:
for (int i = 0; i < k; i++){
In the last loop you will get the same exception cause input[8] doesn't exist.
import java.util.Arrays;
public class CountingSort {
public static void main(String[] args) {
int[] input = {0,1,1,3,4,5,3,0};
int[] output = new int[input.length];
int k = 5; // k is the largest number in the input array
System.out.println("before sorting:");
System.out.println(Arrays.toString(input));
output = countingSort(input, output, k);
System.out.println("after sorting:");
System.out.println(Arrays.toString(output));
}
public static int[] countingSort(int[] input, int[] output, int k) {
int counter[] = new int[k + 1];
for (int i : input) { counter[i]++; }
int ndx = 0;
for (int i = 0; i < counter.length; i++) {
while (0 < counter[i]) {
output[ndx++] = i;
counter[i]--;
}
}
return output;
}
}
Above code is adapted from: http://www.java67.com/2017/06/counting-sort-in-java-example.html
this may help but try using the Arraya.sort() method.
e.g:
//A Java program to sort an array of integers in ascending order.
// A sample Java program to sort an array of integers
// using Arrays.sort(). It by default sorts in
// ascending order
import java.util.Arrays;
public class SortExample
{
public static void main(String[] args)
{
// Our arr contains 8 elements
int[] arr = {13, 7, 6, 45, 21, 9, 101, 102};
Arrays.sort(arr);
System.out.printf("Modified arr[] : %s",
Arrays.toString(arr));
}
}
example is a snippet from https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/
As per algorithm following implementation, I have prepared for the count sort technique
public static int[] countSort(int elements[]) {
int[] sorted = new int[elements.length+1];
int[] range = new int[getMax(elements)+1];
for(int i=0;i<range.length;i++) {
range[i] = getCount(i, elements);
try {
range[i] = range[i]+range[i-1];
}catch(ArrayIndexOutOfBoundsException ae) {
continue;
}
}
for(int i=0;i<elements.length;i++) {
sorted[range[elements[i]]] = elements[i];
range[elements[i]] = range[elements[i]]-1;
}
return sorted;
}
public static int getCount(int value,int[] elements) {
int count = 0;
for(int element:elements) {
if(element==value) count++;
}
return count;
}
public static int getMax(int elements[]) {
int max = elements[0];
for(int i=0;i<elements.length;i++) {
if(max<elements[i]) {
max = elements[i];
}
}
return max;
}
Please review and let me know if any feedback and it is more helpful.
Note :
Non-negative no won't support in the above implementation.
don't use 0th index of the sorted array.

Values of 2 lists are equal, but I'm being told they aren't?

import java.util.Scanner;
public class StrictlyIdentical {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
System.out.print("Enter 5 elements for list1:");
int[] list1 = new int[input.nextInt()];
for (int i = 0; i < list1.length; i++) {
list1[i] = input.nextInt();
}
System.out.print("Enter 5 elements for list2:");
int[] list2 = new int[input.nextInt()];
for (int i = 0; i < list2.length; i++) {
list2[i] = input.nextInt();
}
if (equals(list1, list2)) {
System.out.println("The two lists are strictly identical");
} else {
System.out.println("The two lists are not strictly identical");
}
}
public static boolean equals(int[] list1, int[] list2) {
if (list1.length != list2.length)
return false;
for (int i = 0; i < list2.length; i++) {
if (list1[i] != list2[i])
return false;
}
return true;
}
}
This is what I have. When prompted to enter list 1: I enter 1 2 3 4 5. Then when prompted to enter list 2 I enter 1 2 3 4 5. I keep getting the two lists are not strictly identical, however when all the values in the list are equal and are the same values for both lists then I get the two lists are strictly identical.
The problem is that you are inputing the size of the lists:
int[] list1 = new int[input.nextInt()];
and
int[] list2 = new int[input.nextInt()];
So if you don't enter it before the values, you will have one list of size 1 and the other of size 3.
You can either change the lists to be of fixed size:
int[] list1 = new int[5];
Or change your prompt :
System.out.print("Enter the size of list1 followed by its elements:");
You can also dynamically affect the size of the arrays, but you have to change you code's logic:
System.out.print("Enter elements for list1:");
int[] list1 = Arrays.stream(input.nextLine().split("\\s+")).mapToInt(Integer::parseInt).toArray();
System.out.print("Enter elements for list2:");
int[] list2 = Arrays.stream(input.nextLine().split("\\s+")).mapToInt(Integer::parseInt).toArray();
In this line:
int[] list1 = new int[input.nextInt()];
You actually create a list of size 1 (At least - that's what you write in the input you give), and here:
list1[i] = input.nextInt();
You enter 2 as it's only value.
Furthermore, your Scanner keeps going in the same line as above - creating a second list of size 3 and entering 4,5 and 1.
(Read more here about nextInt() and Scanner)
So, you have two choices:
Get user input about size of list before-hand.
initialize the array with a value, like: int[] arr = new int[5];
Set the array 5 and it is solved.
Equals method is working find as well.
System.out.print("Enter 5 elements for list1:");
int[] list1 = new int[5]; <<<<
for (int i = 0; i < list1.length; i++) {
list1[i] = input.nextInt();
}
System.out.print("Enter 5 elements for list2:");
int[] list2 = new int[5]; <<<<<<
for (int i = 0; i < list2.length; i++) {
list2[i] = input.nextInt();
}
I'd suggest that you go for this problem with lists instead of arrays. That opens
list1.equals(list2) for comparison instead of writing a no way bullet-proof homebrew equals method ;-)
So try it like this:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class StrictlyIdentical {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
System.out.print("Enter 5 elements for list1:");
List<Integer> list1 = new ArrayList<Integer>();
for (int i = 0; i < 5; i++) {
list1.add(input.nextInt());
}
System.out.print("Enter 5 elements for list2:");
List<Integer> list2 = new ArrayList<Integer>();
for (int i = 0; i < 5; i++) {
list2.add(input.nextInt());
}
if (list1.equals(list2)) {
System.out.println("The two lists are strictly identical");
} else {
System.out.println("The two lists are not strictly identical");
}
}
}

Printing all permutations of integer array in Java [duplicate]

This question already has answers here:
Getting permutations of an int[] removing duplicates sets
(5 answers)
Closed 7 years ago.
I've just written a code for printing all the possible permutations from 1 to n in an int array in Java, but I think it is more complex than it needs to be. I am using Hashset to avoid repetitions. If someone finds something than can be simplified, please write.
import java.util.*;
public class ProblemFour {
private static int n;
private static void printResult(int[] result) {
Set<Integer> set = new HashSet<>();
Integer[] nums = new Integer[result.length];
for (int i = 1; i <= n; i++) {
nums[i - 1] = result[i - 1];
}
for (Integer num : nums) {
set.add(num);
}
if(set.size() == n) {
String s = "[ ";
for (Integer num : nums) {
s += num + " ";
}
System.out.println(s + "] ");
}
}
private static void permute(int[] result, int index) {
if (index == result.length) {
printResult(result);
return;
}
for (int i = 1; i <= n; i++) {
result[index] = i;
permute(result, index+1);
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("From 1 to: ");
n = input.nextInt();
int[] result = new int[n];
permute(result, 0);
}
}
I made this permutations code way back it uses lists as a data structure in it.
public List<List<Integer>> permute(int[] numbers) {
// we use a list of lists rather than a list of arrays
// because lists support adding in the middle
// and track current length
List<List<Integer>> permutations = new ArrayList<List<Integer>>();
// Add an empty list so that the middle for loop runs
permutations.add(new ArrayList<Integer>());
for ( int i = 0; i < numbers.length; i++ ) {
// create a temporary container to hold the new permutations
// while we iterate over the old ones
List<List<Integer>> current = new ArrayList<List<Integer>>();
for ( List<Integer> permutation : permutations ) {
for ( int j = 0, n = permutation.size() + 1; j < n; j++ ) {
List<Integer> temp = new ArrayList<Integer>(permutation);
temp.add(j, numbers[i]);
current.add(temp);
}
}
permutations = new ArrayList<List<Integer>>(current);
}
return permutations;
}

bubble sort with recursive method and at the end comper two different arrays

I'm writing a code that ask at the user to insert the numbers of the array and then write each numbers, do the same thing in another array, and at the end compare the first array with the second array and print out the bubble sort of all numbers, so a kind of bubble sort for the first and second array togheter. I wrote this below, but I don t know how to compare with one method the two different arrays.
public static void main(String[] args) {
public static int[] macello(int[]A){
for(int i=0; i<A.length-1; i++){
for(int j=0; j<A.length-1-i;j++){
if(A[j]>A[j+1]){
int temp = A[j+1];
A[j+1]= A[j];
A[j] = temp;
}
}
}
return A;
}
public static void printArray2(int[]A){
for(int i = 0; i<A.length; i++){
System.out.print(A[i]+",");
}
}
Scanner scan = new Scanner(System.in);
System.out.println("Insert the capacity's array1: ");
int n = scan.nextInt();
int[]numbers1 = {n};
for(int i=0; i<n; i++){
System.out.println("Insert the value of each numbers: ");
int j =0;
numbers1[j] = scan.nextInt();
j++;
}
System.out.println("Insert the capacity's array2: ");
int m = scan.nextInt();
int[]numbers2 = {m};
for(int i=0; i<m; i++){
System.out.println("Insert the value of each numbers: ");
int j=0;
numbers2[j] = scan.nextInt();
j++;
}
macello(Arrays.equals(numbers1,numbers2));
printArray2(Arrays.equals(numbers1,numbers2));
}
}
You mention in the comments that you've already solved bubblesort. So I'm going to assume you have a method with the signature void bubbleSort(int[] arr).
Your code shows you understand how to acquire an array from the user, so we don't need to handle that.
Now what you're describing is bubbleSorting these two arrays. To do this, you need one -big- array that holds them both.
int combinedLength = array1.length + array2.length;
int[] combined = new int[combinedLength];
for(int i = 0; i < array1.length; i++) {
combined[i] = array1[i];
}
for(int i = 0; i < array2.length; i++) {
combined[array1.length + i] = array2[i];
}
// now you can bubbleSort
bubbleSort(combined);
arrayPrint(combined);
Ideally you wrap that logic in a merge method - this particular method leverages the Arrays and System classes to do some of the lifting for you. Obviously you could use the "naive" logic above if you want.
int[] merge(int[] a , int[] b) {
int[] c = Arrays.copyOf(a, a.length + b.length);
System.arraycopy(b,0,c,a.length,b.length);
return c;
}
If you also make a method that acquires an array, like this:
public int[] acquireArray(Scanner sc) {
System.out.println("Length? ");
int len = sc.nextInt();
int[] arr = new int[len];
for(int i = 0; i < len; i++) {
System.out.println("Enter element " + (i+1) + ":");
arr[i] = sc.nextInt();
}
return arr;
}
Then your code becomes very, very clean:
Scanner sc = new Scanner(System.in);
int[] a = acquireArray(sc);
int[] b = acquireArray(sc);
int[] c = merge(a,b);
bubbleSort(c);
arrayPrint(c);
I made a driver to test each of these ideas out to make sure they all work. I am a bit concerned, though, because you mention recursion. As you can see in this driver, there is no recursion here. Also be aware that I take a number of shortcuts that are probably not allowed (such as System.arraycopy, Arrays.copyOf, and Arrays.toString). I just wanted to validate the various pieces of functionality. The message uses 1 indexing because that's what most people think in. If you enter 5 elements, they'll be 1-5. You and I know Java stores them 0 indexed, 0-4. It's just a matter of taste and UX.
import java.util.*;
public class BubbleSort {
public static void main(String...args) {
Scanner sc = new Scanner(System.in);
int[] a = acquireArray(sc);
int[] b = acquireArray(sc);
int[] c = merge(a,b);
bubbleSort(c);
printArray(c);
}
public static int[] acquireArray(Scanner sc) {
System.out.println("Length? ");
int len = sc.nextInt();
int[] arr = new int[len];
for(int i = 0; i < len; i++) {
System.out.println("Enter element " + (i+1) + ":");
arr[i] = sc.nextInt();
}
return arr;
}
public static int[] merge(int[] a , int[] b) {
int[] c = Arrays.copyOf(a, a.length + b.length);
System.arraycopy(b,0,c,a.length,b.length);
return c;
}
public static void bubbleSort(int[] a) {
boolean swapped = true;
int j = 0;
while(swapped) {
swapped = false;
j++;
for(int i = 0; i < a.length - j; i++) {
if(a[i] > a[i+1]) {
int t = a[i];
a[i] = a[i+1];
a[i+1] = t;
swapped = true;
}
}
}
}
public static void printArray(int[] a) {
System.out.println(Arrays.toString(a));
}
}
And here's what I get when I run it
C:\files\j>java BubbleSort
Length?
5
Enter element 1:
1
Enter element 2:
5
Enter element 3:
3
Enter element 4:
9
Enter element 5:
7
Length?
5
Enter element 1:
2
Enter element 2:
6
Enter element 3:
4
Enter element 4:
0
Enter element 5:
8
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

counting cosecutive numbers in arrays

Problem H [Longest Natural Successors]
Two consecutive integers are natural successors if the second is the successor of the first in the sequence of natural numbers (1 and 2 are natural successors). Write a program that reads a number N followed by N integers, and then prints the length of the longest sequence of consecutive natural successors. Example:
Input
7 2 3 5 6 7 9 10 Output 3
here is my code so far can anyone help me plz
import java.util.Scanner;
public class Conse {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
int x=scan.nextInt();
int[] array= new int[x];
for(int i=0;i<array.length;i++)
array[i]=scan.nextInt();
System.out.println(array(array));
}
public static int array(int[] array){
int count=0,temp=0;
for(int i=0;i<array.length;i++){
count=0;
for(int j=i,k=i+1;j<array.length-1;j++,k++)
if(array[j]-array[k]==1)
count++;
else{if(temp<count)
temp=count;
break;}
}
return temp+1;
}
}
Try this
ArrayList<Integer> outList = new ArrayList<Integer>()
int lastNum = array[0];
for(int i = 1; i < array.length; i++;)
if((lastNum + 1) == array[i])
outList.add(array[i]);
I think the line i=counter; should be i += counter. otherwise, you're always resetting the loop-counter i to zero, and so it never progresses.
You don't need the inner for loop, as this can be done with one single scan through the array:
public static int consecutive(int[]array) {
int tempCounter = 1; //there will always be a count of one
int longestCounter = 1; //always be a count of one
int prevCell = array[0];
for(int i=1;i<array.length;i++) {
if( array[i] == (prevCell + 1)) {
tempCounter++; //consecutive count increases
} else {
tempCount =1; //reset to 1
}
if(tempCounter > longestCounter) {
longestCounter = tempCounter; //update longest Counter
}
prevCell = array[i];
}
return longestCounter;
}
int sequenceStart = 0;
int sequenceLength = 0;
int longestSequenceLength = 0;
for (int item: array) {
if (item == sequenceStart + sequenceLength) {
sequenceLength++;
} else {
sequenceStart = item;
sequenceLength = 1;
}
longestSequenceLength = Math.max(longestSequenceLength, sequenceLength);
}

Categories