Why is the program not ordering the array? - java

I'm making a program that arranges an array by moving the largest value to the end but for some reason, the program isn't arranging the values menually.
How can I fix that?
public static void main(String args[]) {
ArrayList<Integer> list = new ArrayList<>();
list.add(15);
list.add(78);
list.add(44);
list.add(99);
list.add(32);
int num = 1;
for(int i = 0; i<=list.size() -1;){
if(list.get(i) > list.get(i+1)){
list.add(list.get(i));
list.remove(i);
System.out.println(list);
}
else{
i+=1;
num+=1;
}
}
}
and this what I'm getting:
[15, 44, 99, 32, 78]
[15, 44, 32, 78, 99]
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 5 out of bounds for length 5
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at MyClass.main(MyClass.java:10)

This works:
public static void main(String args[]) {
ArrayList<Integer> list = new ArrayList<>();
list.add(15);
list.add(78);
list.add(44);
list.add(99);
list.add(32);
for(int i = 0; i < list.size() - 1; i++){
for(int j = 0; j < list.size() - i - 1; j++){
if(list.get(j) > list.get(j + 1)){
int temp = list.get(j);
list.set(j, list.get(j + 1));
list.set(j + 1, temp);
}
}
}
System.out.println(list);
}

First off, it's usually a bad idea to add and/or remove items to a list while looping over it. You are lucky it's working here, because you are adding and removing the same number of items, but it would be better to swap the items at the i and last positions:
int last = list.get(list.size() - 1);
list.set(list.size() - 1) = list.get(i);
list.set(i) = last;
But to your problem: The index of your loop (i) goes from 0 to 4. In the last loop, when you try to list.get(i+1) you attempt to get index 4+1 = 5, but the list only has size of 5, so there is no index 5.
In your case you need to loop to only until the second last index, not the last:
for(int i = 0; i<=list.size() - 2;){
// Change from 1 to 2 ----^

Below code like is the reason for IndexOutOfBoundsException. when i = 4, i + 1 = 5 and no index matching in the List.
if(list.get(i) > list.get(i+1)){
If you want to try the bubble sort you could try below
for (int i = list.size() - 1; i >= 0; i--)
for (int j = 0; j < i; j++) {
if (list.get(j) > list.get(j + 1)) {
int temp = list.get(j);
list.set(j, list.get(j + 1));
list.set(j + 1, temp);
}
}
System.out.println(list);
If your intention is to sort without your own code, you could use
Collections.sort(list);

If you wanna sort manually then this code works :
while ( i < list.size()-1) {
if(list.get(i) > list.get(i+1)){
list.add(list.get(i));
list.remove(i);
i--;
} else {
i++;
}
}
But for efficiency I would suggest you to use :
Collections.sort(list);

Related

Selection Sort wrong output

I am trying to understand the SelectionSort for arrays.
If I understand it correctly, it compares the element[minimum] with the next elements element[i] and swaps positions if element[i] < element[minimum]. Then it repeats this with element[i + 1] until the list is sorted.
Now when I try it with the following code, I get an incorrect sort and can't figure out what I'm doing wrong.
public static void SelectionSort1(int[] list){
for (int i = 0; i < (list.length - 1); i++){
int min = i;
for (int j = i + 1; j<list.length; j++){
if(list[j] < list[min]){
min = j;
}
int smallernumber = list[i];
list[i] = list[min];
list[min] = smallernumber;
}
}
}
public static void main (String [] args){
int[] list = {5,4,2,1,3};
System.out.println("Before Sort" + Arrays.toString(list));
SelectionSort1(list);
System.out.println("After Sort " + Arrays.toString(list));
}
My output is:
Before Sort[5, 4, 2, 1, 3]
After Sort [2, 3, 1, 4, 5]
Can anyone point me in the right direction?
Your understanding is almost correct, it compares the element[minimum] with the next elements element[j] and if element[j] < element[minimum] then the minimum index is equal to j. Then it repeats until j reaches the end of the array. After it swaps the index at element[i] with element[minimum].
What this is doing is swapping element[i] with the smallest number to the right of index i. Then moving index i to the next spot. Repeating this gives you a sorted array.
TLDR:
Move the swapping outside of the second for loop. It should be:
public static void SelectionSort1(int[] list){
for (int i = 0; i < (list.length - 1); i++){
int min = i;
for (int j = i + 1; j<list.length; j++){
if(list[j] < list[min]){
min = j;
}
}
int smallernumber = list[i];
list[i] = list[min];
list[min] = smallernumber;
}
}

Duplicate zero in array by modifying the array in place

There is a fixed length array arr of integers, duplicate each occurrence of zero, shifting the remaining elements to the right. The elements beyond the length of the original array are not written.
We have to modify input array in place and doesn't have to create new array.
So I created that but it is duplicating the zero which is at the end of array and not the previous zeros. Can somebody help me with this?
public static void addPos() {
int arr[] = { 1, 2, 0, 3, 0, 5, 0, 7, 8 };
int result[] = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
int loc = i;
for (int j = 0; j < loc; j++) {
result[j] = arr[j];
result[loc] = 0;
}
for (int j = loc + 1; j < arr.length; j++) {
result[j] = arr[j - 1];
}
}
}
for (int k = 0; k < arr.length; k++)
System.out.println(result[k]);
}
Output
1
2
0
3
0
5
0
0
7
Expected output:
1
2
0
0
3
0
0
5
0
Every iteration of the loop overwrites the results from the previous iteration, so the end result only shows the results from the last iteration, which duplicates the last 0 is duplicated.
One way to solve this is by iterating backwards "right to left". It simplifies a lot of things. You can get rid of the auxiliary result array. The basic idea is, go backwards in the array, and every time you find a 0, you duplicate it by rewriting the array to the right of the zero.
public static void addPos() {
int arr[] = {1, 2, 0, 3, 0, 5, 0, 7, 8};
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] == 0) {
// duplicate it!
for (int j = arr.length - 1; j > i; j--) {
arr[j] = arr[j-1];
}
}
}
for (int k = 0; k < arr.length; k++) {
System.out.println(arr[k]);
}
}
The for loop keeps overwriting the values in result array, hence the result shows only last duplication.You should not be using the result array at all.Keep shipting values in the original array itself.
You can refer to below code.
for(int i=0;i<arr.length-1;i++){
if(arr[i]==0){
for(int j=arr.length-1;j>i;j--){
arr[j]=arr[j-1];
}
i++;
}
}
public void duplicateZeros(int[] arr)
{
int i=0;
while(i<arr.length)
{
if(arr[i]==0)
{
int j=arr.length-1;
while(j != i)
{
arr[j]=arr[j-1];
j--;
}
i=i+2;
}
else
{
i=i+1;
}
}
}
Without using any other Array.
class Solution {
public void duplicateZeros(int[] arr) {
for(int i=0;i<arr.length;i++){
if(arr[i]==0){
for(int j=arr.length-1;j>i;j--){
arr[j]=arr[j-1];
}
i=i+1;
}
}
}
}
So one has this:
int[] arr = { 1, 2, 0, 3, 0, 5, 0, 7, 8 };
public static void duplicateZeros(int[] arr) {
and should get
{ 1, 2, 0, 3, 0, 5, 0, 7, 8 }
v___
{ 1, 2, 0, 0, 3, 0, 5, 0, 7 }
v___
{ 1, 2, 0, 0, 3, 0, 0, 5, 0 }
This looks like:
for (int i = 1; i < n; ++i) {
if (arr[i - 1] == 0) {
insert at i a 0;
}
}
insert at i a 0:
// First move the remaining to the right: i .. n-2
...
// Then fill in the zero
arr[i] = 0;
Python solution for anyone interested adapted from here
the solution is non-trivial if you do not separate the action of the pointer iterating over the list and the insertions. It's very easy to write a for-loop that adds 0's ad-infinitum.
def duplicateZeros(arr):
# define the incrementor
i = 0
# loop through all dynamic elements
while i < len(arr)-1:
# if the character is a zero
if arr[i]==0:
# remove the last item from the array
arr.pop()
# insert a zero in front of current element
arr.insert(i+1, 0)
# move one place forward
i += 1
# increment to the next character
i += 1
Solution 1: Loop from start to end. If zero is found, move the elements from next index and fill the next as zero and skip next.
public static void duplicateZeros(int[] arr) {
System.out.println("BEGIN duplicateZeros:" + Arrays.toString(arr));
for(int i=0; i<arr.length-1; ++i) {
if (arr[i] == 0) {
move(arr, i);
++i;
}
}
System.out.println("END duplicateZeros:" + Arrays.toString(arr) +"\n");
}
private static void move(int[] arr, int index) {
// move to the right from index+1
for(int i=arr.length-1; i>index; i--) {
arr[i] = arr[i-1];
}
// fill 0 at index
arr[index] = 0 ;
}
Solution2: Loop from end to start. If zero is found, move the elements from next index and fill the current index as zero.
public static void duplicateZeros(int[] arr) {
System.out.println("BEGIN duplicateZeros:" + Arrays.toString(arr));
for(int i=arr.length-1; i>=0; i--) {
if (arr[i] == 0) {
move(arr, i);
}
}
System.out.println("END duplicateZeros:" + Arrays.toString(arr) +"\n");
}
private static void move(int[] arr, int index) {
// move to the right from index+1
for(int i=arr.length-1; i>index; i--) {
arr[i] = arr[i-1];
}
// fill 0 at index
arr[index] = 0 ;
}
class Solution:
def duplicateZeros(self, arr: List[int]) -> None:
"""
Do not return anything, modify arr in-place instead.
"""
if len(arr)==0:
return arr
index = 0
while index < len(arr):
print(index,end=" ")
if arr[index]==0:
arr.insert(index+1,0)
arr.pop()
index+=1
index+=1

How can I solve the 3-sum challenge using arrayLists?

I'm currently trying to solve the "three sum" challenge (I'm using java by the way). Here is the challenge description:
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
Here is my attempted solution but it is not working currently:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> subList = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
for (int j = i + 1; j < nums.length - 1; j++) {
for (int k = j + 1; k < nums.length; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
subList.add(nums[i]);
subList.add(nums[j]);
subList.add(nums[k]);
}
}
}
}
result.add(subList);
return result;
}
}
The output I'm getting is:
[[-1,0,1,-1,2,-1,0,1,-1]]
When it is supposed to be:
[[-1,-1,2],[-1,0,1]]
I know my attempted solution is O(n^(3)) and not optimal, but I'm curious on how I can do this challenge using three for loops. Can someone give me an idea on how I can go about creating the right output ? I've been trying different things to no avail. Thank you !
After finding a solution, pleas instantly add it to the results list:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
for (int j = i + 1; j < nums.length - 1; j++) {
for (int k = j + 1; k < nums.length; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
List<Integer> subList = new ArrayList<>();
subList.add(nums[i]);
subList.add(nums[j]);
subList.add(nums[k]);
result.add(subList);
}
}
}
}
return result;
}
}
This will give you:
[[-1,0,1],[-1,2,-1],[0,1,-1]]
In this case, the [-1,0,1] option is added twice, because -1 is in the list twice, depending whether or not you want this, you can sort the sublist, and check for equality:
public class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
for (int j = i + 1; j < nums.length - 1; j++) {
for (int k = j + 1; k < nums.length; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
List<Integer> subList = new ArrayList<>();
subList.add(nums[i]);
subList.add(nums[j]);
subList.add(nums[k]);
Collections.sort(subList);
boolean duplicate = false;
for (List<Integer> list : result) {
if (list.equals(subList)) {
duplicate = true;
break;
}
}
if (!duplicate) {
result.add(subList);
}
}
}
}
}
return result;
}
}
Put result.add(subList) inside of your if statement after your subList.add() statements. Currently in your code, you are adding every solution to the sublist without ever adding it to the result, so at the end you simply are adding a list of ints.
You have 2 issues here:
result.add(subList); You're adding your sublist at the very end of the computations.
You never clear previous results from your sublist.
You need to declare:
List<Integer> subList = new ArrayList<>();
Inside the 2nd loop and before the 3rd one AND add your sublist after you've added all 3 numbers but only if there was a coincidence (i.e. all 3 numbers added are equal to zero)
for (int i = 0; i < nums.length - 2; i++) {
for (int j = i + 1; j < nums.length - 1; j++) {
List<Integer> subList = new ArrayList<>();
for (int k = j + 1; k < nums.length; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
subList.add(nums[i]);
subList.add(nums[j]);
subList.add(nums[k]);
}
}
if (!subList.isEmpty()) {
result.add(subList);
}
}
}
This provides this result:
[[-1, 0, 1], [-1, 2, -1], [0, 1, -1]]
And now we need to have them as unique combinations, so, we could use:
Collections.sort(sublist)
And change our result variable to be a Set rather than a List, so, our code will end up as:
import java.util.*;
class Solution {
public static Set<List<Integer>> threeSum(int[] nums) {
Set<List<Integer>> result = new HashSet<>();
for (int i = 0; i < nums.length - 2; i++) {
for (int j = i + 1; j < nums.length - 1; j++) {
List<Integer> subList = new ArrayList<>();
for (int k = j + 1; k < nums.length; k++) {
if (nums[i] + nums[j] + nums[k] == 0) {
subList.add(nums[i]);
subList.add(nums[j]);
subList.add(nums[k]);
}
}
Collections.sort(subList);
if (!subList.isEmpty()) {
result.add(subList);
}
}
}
return result;
}
public static void main(String[] args) {
System.out.println(threeSum(new int[] {-1, 0, 1, 2, -1, -4}));
}
}
This returns:
[[-1, -1, 2], [-1, 0, 1]]
Note: I made the method static in order to test the program without creating an instance of the class.
You have two problems. The first and most obvious is that you've merely appended the elements to the array, without making a 3-element sub-array from them. You can fix that easily:
subList.add(nums[i]);
subList.add(nums[j]);
subList.add(nums[k]);
Should be
subList.add([nums[i], nums[j], nums[k]);
The second problem is that your program doesn't recognize that the -1 values are not considered separate solutions to the remaining pair of [1, 0]. The easiest way to get around this is to sort the list before you begin, and check that your third element can be only one of any grouping.
Finally, to consolidate the gains of that sorting, your loop nesting should ensure that you never pick the same elements in a different order. You're handling your indexing correctly, but eliminate the third loop. Merely check to see whether the sum you need is available. In pseudo-code ...
if (-(nums[i] + nums[j]) is in nums[j+1:])
kotlin way
fun main() {
println(ThreeSum(readLine()))
}
fun ThreeSum(nums: Array<Int>): Boolean {
if(nums.size < 4) return false //minimum 4 elements should be in array
var counter = 0
for (i in 0..(nums.size - 3)) {
for (j in (i + 1)..(nums.size - 3)) {
for (k in (j + 1)..(nums.size-1)) {
if (nums[i] + nums[j] + nums[k] == nums[0]) {
counter+=1
if (counter == 3) {
return true
}
}
}
}
}
return false
}
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> three=new ArrayList<>();
for(int i=0;i<nums.length-2;i++){
for(int j=i+1;j<nums.length-1;j++){
for(int k=j+1;k<nums.length;k++){
List<Integer> list=new ArrayList<>();
if(nums[i]+nums[j]+nums[k]==0){
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
Collections.sort(list);
boolean duplicate = false;
for (List<Integer> l : three) {
if (three.equals(list)) {
duplicate = true;
break;
}
}
if (!duplicate) {
if(!three.contains(list)){
three.add(list);
}
}
}
}
}
}
return three;
}
}

Reverse3 ArrayList

given an Array List with the values [10, 13, 2, 8, 7, 90, -1, 2]. I have to create a method that will reverse each successive sequence of 3 values within said list. For example (10, 13, 2) will become (2,13 10) and the (8, 7, 90) will become (90,7,8) However, it will not print out numbers that aren't part of a sequence of 3. So far this is what I have:
public static ArrayList<Integer> reverse3(ArrayList<Integer> list) {
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int i = 0; i <list.size()-1; i++){
for(int j = list.size()-1; j >= 0 ; j--){
newList.add(list.get(j));
}
}
return newList;
I'm having issues getting this to work properly. The output reverses the sequences of three but -1 and 2 are printed as well.
It sounds like all you really need to do is to swap 1 and 3, 2 and 4 etc. So:
for (int i = 0; i < list.size(); i += 3) {
Collections.swap(list, i, i + 2);
for (int j = i; j < i + 3; j++)
System.out.println(list.get(j) + " ");
}
Or you could just print them out without even swapping the items:
for (int i = 0; i < list.size(); i += 3) {
for (int j = i + 2; j >= i; j--)
System.out.println(list.get(j) + " ");
}
And here's a solution using sublist and Java 8 streams:
IntStream.range(0, list.size() / 3)
.mapToObj(n -> list.sublist(n, n + 3))
.map(Collections::reverse)
.flatMap(List::stream)
.forEach(System.out::println);
Since it looks like it's "do my homework for free" day today,
for extra credit, write it in scala:
list
.grouped(3)
.map(_.reverse)
.flatten
.toList
Something like that should do it:
for( int i = 1; i < list.size()-1; i+=3 ) {
int tmp = list.get(i+1);
list.set(i+1, list.get(i-1));
list.set(i-1, tmp);
}
This is the code you need:
public static ArrayList<Integer> reverse3(List<Integer> list) {
ArrayList<Integer> newList = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i+=3) {
for (int j = i+2; j >= i && j < list.size(); j--) {
newList.add(list.get(j));
}
}
return newList;
}
This is a demo:
public static void main(String[] args) {
List<Integer> list = Arrays.asList(10, 13, 2, 8, 7, 90, -1, 2);
System.out.println(list);
System.out.println(reverse3(list));
}
Input: [10, 13, 2, 8, 7, 90, -1, 2]
Results: [2, 13, 10, 90, 7, 8]

Bubble Sort compiling but out of bounds

I am having issues with getting a simple bubble sort of an array to work properly.
It compiles, but I'm getting an out of bounds exception when running the program.
I know what an out of bounds error is but I can't see why it occurred in this case.
Any geniuses there that know how to fix this? Thank you
public class BubbleSort
{
public static void main(String[] args)
{
// create the array that we want to sort with buble sort alogorithm
int intArray[] = new int[]{5, 90, 35, 45, 150, 3};
//print the array before the bubble sort
System.out.println("Array before Bubble Sort");
for (int i = 0; i < intArray.length; i++)
{
System.out.print(intArray[i] + " ");
}
// sort an array using bubble sort algorithm
bubbleSort(intArray);
System.out.println("");
// print array after sorting using bubble sort
System.out.println("Array after Bubble Sort");
for (int i = 0; i < intArray.length; i++)
{
System.out.print(intArray[i] + "");
}
}
private static void bubbleSort(int[] intArray)
{
int n = intArray.length;
int hold = 0;
for (int i = 0; i < n; i++) //allows us to pass or loop around array
{
for (int j = 1; j < (n - i); j++) //allows on pass or comparison
{
if (intArray[j] > intArray[j + 1]) //swap the elements!
{
hold = intArray[j];
intArray[j] = intArray[j + 1];
intArray[j + 1] = hold;
}
}
}
}
}
In the first iteration of the outer loop, i==0.
Therefore in the inner loop j would go from 1 to n-i-1==n-1.
When j==(n-1), intArray[j+1] would throw ArrayIndexOutOfBoundsException.
On the first iteration of the outer loop of your bubbleSort method, when i is equal to zero, j is allowed to go up to n-i-1, inclusive, i.e. the last value of j is going to be n-1.
When this happens, inArray[j+1] will be out of bounds, because it would be equivalent to inArray[n]. The last valid index is n-1.
to fix this, make sure that the outer loop starts at i=1 instead of i=0.
I commented on the lines where you made a mistake
public static class BubbleSort { //you need static here
public static void main(String[] args) {
int intArray[] = new int[] { 5, 90, 35, 45, 150, 3 };
System.out.println("Array before Bubble Sort");
for (int i = 0; i < intArray.length; i++) {
System.out.print(intArray[i] + " ");
}
bubbleSort(intArray);
System.out.println("");
System.out.println("Array after Bubble Sort");
for (int i = 0; i < intArray.length; i++) {
System.out.print(intArray[i] + " "); // you need space between the parenthesis so that results show up readable
}
}
private static void bubbleSort(int[] intArray) {
int n = intArray.length;
int hold = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < (n - i - 1); j++){ // j has to be equal to 0, or your first value in the array won't get compared, and -1 because of the array out of bounds error
if (intArray[j] > intArray[j + 1]){
hold = intArray[j];
intArray[j] = intArray[j + 1];
intArray[j + 1] = hold;
}
}
}
}
}
public class BubbleSort
{
public static void main (String[]args)
{
// create the array that we want to sort with buble sort alogorithm
int intArray[] = new int[] {5, 90, 35, 45, 150, 3};
//print the array before the bubble sort
System.out.println ("Array before Bubble Sort");
for (int i = 0 ; i intArray[j+1]) //swap the elements!
{
hold = intArray[j];
intArray[j] = intArray[j + 1];
intArray[j + 1] = hold;
}
}
}
}
}
Replace j < (n-i) with j < (n-i)-1.
Reason
In the last iteration, j will have a value equal to one less than the length of the array(ie it points to the last element). But when you compare elements with index j+1, you are pointing to an out of bound element. Thus the exception. Hope it helps.
(this is to answer your question about 3 not being the first value displayed)
code should go like this if you want in assenting order
you have missed for( int j=0; j<(n-i-1); j++
for (int i=0; i<n; i++) //loop trough array
{
for( int j=0; j<(n-i-1); j++) //loop allows variable j pass on for comparison
{
if ( intArray[j]> intArray[j+1]) // if current slot in array j is bigger than the next one

Categories