I have created a method, which is supposed to return a growing number list when entered any number.
For example:
input: 5
expected output: [1, 2 2, 3 3 3, 4 4 4 4, 5 5 5 5 5]
current output : [1 , 2 2 , 3 3 3 , 4 4 4 4 , 5 5 5 5 5 ]
input: 2
expected output: [1, 2 2]
current output : [1 , 2 2 ]
How do I delete the white spaces?
This is my code:
ArrayList < String > maxarray = new ArrayList < String > ();
int i, j;
String num = "";
for (i = 1; i <= max; i++) {
num = "";
for (j = 1; j <= i; j++) {
num = num + i + " ";
}
//System.out.print(i);
maxarray.add(num);
}
return maxarray;
I have tried: num= num.replace(" ","");
num = num.replace(" ", "");
but, they don't seem work.
and if I try to convert it into a string, I get the following output: 1 2 2 3 3 3
Help me, please
Easy and short-sighted solution: just trim the string before adding it to the ArrayList:
maxarray.add(num.trim());
With this change the output is:
[1, 2 2, 3 3 3, 4 4 4 4, 5 5 5 5 5]
trim() removes trailing spaces (and leading, had there been any), but not the spaces between the numbers.
Produce correct output from the outset: However, rather than producing not-quite-right output and then correcting it it’s probably less confusing in the end to produce correct output from the outset. That is, without the space after the last number. This is also what the answer by Berto99 does. My preferred way of doing this is: take one iteration out of the inner loop and refrain from adding the space there.
for (i = 1; i <= max; i++) {
num = "";
for (j = 1; j < i; j++) { // stop one number before i
num = num + i + " ";
}
num = num + i; // add no space here
maxarray.add(num);
}
Output still is:
[1, 2 2, 3 3 3, 4 4 4 4, 5 5 5 5 5]
I find this way easier to read than the version with the extra if statement in the answer by Berto99.
For the sake of precision: maxarray is not an int array, it as an ArrayList of strings. And what we needed to trim was not the ArrayList but each string in it.
PS Stream version: For readers who know and like streams here’s a stream version. If you don’t want to learn about streams yet, just ignore.
List<String> maxarray = IntStream.rangeClosed(1, max)
.mapToObj(i -> IntStream.rangeClosed(1, i)
.mapToObj(j -> String.valueOf(i))
.collect(Collectors.joining(" ")))
.collect(Collectors.toList());
One of the convenient things is that Collectors.joining(" ") puts spaces between the numbers without putting any space before the first or after the last, which solves the problem asked about.
As you can see from here:
ArrayList < String > maxarray = new ArrayList < String > ();
int i, j;
String num = "";
for (i = 1; i <= max; i++) {
num = "";
for (j = 1; j <= i; j++) {
num = num + i + " ";
^^^^-- here
}
//System.out.print(i);
maxarray.add(num);
}
return maxarray;
you add a space after every number, so you only need to check if you are not in the last number, in order not to add the space in that case:
ArrayList < String > maxarray = new ArrayList < String > ();
int i, j;
String num = "";
for (i = 1; i <= max; i++) {
num = "";
for (j = 1; j <= i; j++) {
num = num + i;
if(j < i) // <--- check if you are not in the last iteration
num = num + " ";
}
//System.out.print(i);
maxarray.add(num);
}
return maxarray;
Related
Sample input:
45 8 4 10 44 43 12 9 8 2
First number = N
Second number = T
Following T numbers = A set of values
My job is to find the subset where the sum is the highest possible one out of all subsets, that doesn't exceed N. Print that set, and the sum. So, output for that input would be:
2 8 9 12 10 4 sum:45
My issue is, I don't have something to decide between tiebreakers. The tiebreaking factor would be the set with larger amount of elements. So my program prints this:
2 43 sum:45
Here is the code (standard I/O):
int val = reader.nextInt();
int num = reader.nextInt(); // never exceeds 20
int[] cost = new int[20];
int[][] dp = new int[10000][10000];
int[][] path = new int[10000][10000];
for (int i = 0; i < num; i++) {
cost[i] = reader.nextInt();
}
for (int i = 0; i < num; i++) {
for (int j = 0; j <= val; j++) {
if (j < cost[i]) {
dp[i + 1][j] = dp[i][j];
}
else {
if (dp[i][j] < dp[i][j - cost[i]] + cost[i]) {
path[i+1][j] = 1;
dp[i + 1][j] = dp[i][j - cost[i]] + cost[i];
}
else {
dp[i + 1][j] = dp[i][j];
}
}
}
}
int k = val;
for (int i = num; i >= 1; i--) {
if (path[i][k] == 1 && k >= 0) {
System.out.print(cost[i - 1] + " ");
k = k - cost[i - 1];
}
}
System.out.print("sum:" + dp[num][val] + '\n');
You are on the right track with your T x N 2-dimensional array. But you shouldn't be tracking the accumulated cost as the value of each cell, that is already tracked by the 2nd index (j in your case). Instead, track the maximum number of elements you can sum to get to that cost so far. By doing this, you don't even need a path array.
Imagine a scenario where N = 5, T = 4, and the numbers are {4, 1, 1, 3}. The first column would track a 1 in the row j == 4 and 0 everywhere else. The second column would track a 2 in the row j == 5, a 1 in rows j == 4 and j == 1 and 0 everywhere else. You could fill it with something like this (may need some tweaking...):
dp[0][cost[0]] = 1;
for (int i = 1; i < T; i++) {
dp[i][cost[i]] = 1;
for (int j = N - 1; j >= 0; j--) {
if (j >= cost[i] && dp[i-1][j-cost[i]] > 0) {
dp[i][j] = dp[i-1][j-cost[i]] + 1;
}
dp[i][j] = Math.max(dp[i][j], dp[i-1][j]);
}
}
The dp table at the end would look like this:
Sum (j)
5 | 0 2 2 3
4 | 1 1 1 2
3 | 0 0 0 1
2 | 0 0 2 2
1 | 0 1 1 1
0 | 0 0 0 0
______________________________
cost | { 4 1 1 3 }
From this table, you know that the maximum number of elements you can use to sum to 5 is 3. To find out what those elements are, work backwards from dp[3][5]. Since dp[2][5] != dp[3][5], you must have added cost[3] (3) as your third element, so add 3 to your result set. The next value to inspect is dp[2][5 - cost[3]], or dp[2][2]. Compare that to the cell to the left, dp[1][2]. They aren't equal, so you must have added cost[2] as well (if they were equal, that means you didn't add cost[2], and the next cell to inspect would be dp[1][2]). Continue until dp[i][j] == 0 or i == 0 to construct your result set.
I was going through a simple program that takes a number and finds the number of occurrences of consecutive numbers that matches with given number.
For example:
if input is 15, then the consecutive numbers that sum upto 15 are:
1,2,3,4,5
4,5,6
7,8
So the answer is 3 as we have 3 possibilities here.
When I was looking for a solution I found out below answer:
static long process(long input) {
long count = 0;
for (long j = 2; j < input/ 2; j++) {
long temp = (j * (j + 1)) / 2;
if (temp > input) {
break;
}
if ((input- temp) % j == 0) {
count++;
}
}
return count;
}
I am not able to understand how this solves the requirement because this program is using some formula which I am not able to understand properly, below are my doubts:
The for loop starts from 2, what is the reason for this?
long temp = (j * (j + 1)) / 2; What does this logic indicates? How is this helpful to solving the problem?
if ((num - temp) % j == 0) Also what does this indicate?
Please help me in understanding this solution.
I will try to explain this as simple as possible.
If input is 15, then the consecutive numbers that sum upto 15 are:
{1,2,3,4,5} -> 5 numbers
{4,5,6} -> 3 numbers
{7,8} -> 2 numbers
At worst case, this must be less than the Sum of 1st n natural numbers = (n*(n+1) /2.
So for a number 15, there can never be a combination of 6 consecutive numbers summing up to 15 as the sum of 1st 6 numbers =21 which is greater than 15.
Calculate temp: This is (j*(j+1))/2.
Take an example. Let input = 15. Let j =2.
temp = 2*3/2 = 3; #Meaning 1+2 =3
For a 2-number pair, let the 2 terms be 'a+1' and 'a+2'.(Because we know that the numbers are consecutive.)
Now, according to the question, the sum must add up to the number.
This means 2a+3 =15;
And if (15-3) is divisible by 2, 'a' can be found. a=6 -> a+1=7 and a+2=8
Similarly, let a+1 ,a+2 and a+3
a + 1 + a + 2 + a + 3 = 15
3a + 6 = 15
(15-6) must be divisible by 3.
Finally, for 5 consecutive numbers a+1,a+2,a+3,a+4,a+5 , we have
5a + 15 = 15;
(15-15) must be divisible by 5.
So, the count will be changed for j =2,3 and 5 when the input is 15
If the loop were to start from 1, then we would be counting 1 number set too -> {15} which is not needed
To summarize:
1) The for loop starts from 2, what is the reason for this?
We are not worried about 1-number set here.
2) long temp = (j * (j + 1)) / 2; What does this logic indicates? How is this helpful to solving the problem?
This is because of the sum of 1st n natural numbers property as I have
explained the above by taking a+1 and a+2 as 2 consecutive
numbers.
3) if ((num - temp) % j == 0) Also what does this indicate?
This indicates the logic that the input subtracted from the sum of 1st
j natural numbers must be divisible by j.
We need to find all as and ns, that for given b the following is true:
a + (a + 1) + (a + 2) + ... (a + (n - 1)) = b
The left side is an arithmetic progression and can be written as:
(a + (n - 1) / 2) * n = b (*)
To find the limit value of n, we know, that a > 0, so:
(1 + (n - 1) / 2) * n = n(n + 1) / 2 <= b
n(n + 1) <= 2b
n^2 + n + 1/4 <= 2b + 1/4
(n + 1/2)^2 <= 2b + 1/4
n <= sqrt(2b + 1/4) - 1/2
Now we can rewrite (*) to get formula for a:
a = b / n - (n - 1) / 2
Example for b = 15 and n = 3:
15 / 3 - (3 - 1) / 2 = 4 => 4 + 5 + 6 = 15
And now the code:
double b = 15;
for (double n = 2; n <= Math.ceil(Math.sqrt(2 * b + .25) - .5); n++) {
double candidate = b / n - (n - 1) / 2;
if (candidate == (int) candidate) {
System.out.println("" + candidate + IntStream.range(1, (int) n).mapToObj(i -> " + " + (candidate + i)).reduce((s1, s2) -> s1 + s2).get() + " = " + b);
}
}
The result is:
7.0 + 8.0 = 15.0
4.0 + 5.0 + 6.0 = 15.0
1.0 + 2.0 + 3.0 + 4.0 + 5.0 = 15.0
We are looking for consecutive numbers that sum up to the given number.
It's quite obvious that there could be at most one series with a given length, so basically we are looking for those values witch could be the length of such a series.
variable 'j' is the tested length. It starts from 2 because the series must be at least 2 long.
variable 'temp' is the sum of a arithmetic progression from 1 to 'j'.
If there is a proper series then let X the first element. In this case 'input' = j*(X-1) + temp.
(So if temp> input then we finished)
At the last line it checks if there is an integer solution of the equation. If there is, then increase the counter, because there is a series with j element which is a solution.
Actually the solution is wrong, because it won't find solution if input = 3. (It will terminate immediately.) the cycle should be:
for(long j=2;;j++)
The other condition terminates the cycle faster anyway.
NB: loop is starting from 2 because=> (1*(1+1))/2 == 1, which doesn't make sense, i.e, it doesn't effect on the progress;
let, k = 21;
so loop will iterate upto (k/2) => 10 times;
temp = (j*(j+1))/2 => which is, 3 when j =2, 6 when j = 3, and so on (it calculates sum of N natural numbers)
temp > k => will break the loop because, we don't need to iterate the loop when we got 'sum' which is more than 'K'
((k-temp)%j) == 0 => it is basically true when the input subtracted from the sum of first j natural numbers are be divisible by j, if so then increment the count to get total numbers of such equation!
public static long process(long input) {
long count = 0, rest_of_sum;
for (long length = 2; length < input / 2; length++) {
long partial_sum = (length * (length + 1)) / 2;
if (partial_sum > input) {
break;
}
rest_of_sum = input - partial_sum
if (rest_of_sum % length == 0)
count++;
}
return count;
}
input - given input number here it is 15
length - consecutive numbers length this is at-least 2 at max input/2
partial_sum = sum of numbers from 1 to length (which is a*(a+1)/2 for 1 to a numbers) assume this is a partial sequence
rest_of_sum = indicates the balance left in input
if rest of sum is multiple of length meaning is that we can add (rest_of_sum/length) to our partial sequence
lets call (rest_of_sum/length) as k
this only means we can build a sequence here that sums up to our input number
starting with (k+1) , (k+2), ... (k+length)
this can validated now
(k+1) + (k+2) + ... (k+length)
we can reduce this as k+k+k+.. length times + (1+2+3..length)
can be reduced as => k* length + partial_sum
can be reduced as => input (since we verified this now)
So idea here is to increment count every-time we find a length which satisfies this case here
If you put this tweak in it may fix code. I have not extensively tested it. It's an odd one but it puts the code through an extra iteration to fix the early miscalculations. Even 1/20000 would work! Had this been done with floats that got rounded down and 1 added to them I think that would have worked too:
for (long j = 2; j < input+ (1/2); j++) {
In essence you need to only know one formula:
The sum of the numbers m..n (or m to n) (and where n>m in code)
This is ((n-m+1)*(n+m))/2
As I have commented already the code in the original question was bugged.
See here.
Trying feeding it 3. That has 1 occurrence of the consecutive numbers 1,2. It yields 0.
Or 5. That has 2,3 - should yield 1 too - gives 0.
Or 6. This has 1,2,3 - should yield 1 too - gives 0.
In your original code, temp or (j * (j + 1)) / 2 represented the sum of the numbers 1 to j.
1 2 3 4 5
5 4 3 2 1
=======
6 6 6 6 6 => (5 x 6) /2 => 30/2 => 15
As I have shown in the code below - use System.out.println(); to spew out debugging info.
If you want to perfect it make sure m and n's upper limits are half i, and i+1 respectively, rounding down if odd. e.g: (i=15 -> m=7 & n=8)
The code:
class Playground {
private static class CountRes {
String ranges;
long count;
CountRes(String ranges, long count) {
this.ranges = ranges;
this.count = count;
}
String getRanges() {
return this.ranges;
}
long getCount() {
return this.count;
}
}
static long sumMtoN(long m, long n) {
return ((n-m+1)* (n+m))/2;
}
static Playground.CountRes countConsecutiveSums(long i, boolean d) {
long count = 0;
StringBuilder res = new StringBuilder("[");
for (long m = 1; m< 10; m++) {
for (long n = m+1; n<=10; n++) {
long r = Playground.sumMtoN(m,n);
if (d) {
System.out.println(String.format("%d..%d %d",m,n, r));
}
if (i == r) {
count++;
StringBuilder s = new StringBuilder(String.format("[%d..%d], ",m,n));
res.append(s);
}
}
}
if (res.length() > 2) {
res = new StringBuilder(res.substring(0,res.length()-2));
}
res.append("]");
return new CountRes(res.toString(), count);
}
public static void main(String[ ] args) {
Playground.CountRes o = countConsecutiveSums(3, true);
for (long i=3; i<=15; i++) {
o = Playground.countConsecutiveSums(i,false);
System.out.println(String.format("i: %d Count: %d Instances: %s", i, o.getCount(), o.getRanges()));
}
}
}
You can try running it here
The output:
1..2 3
1..3 6
1..4 10
1..5 15
1..6 21
1..7 28
1..8 36
1..9 45
1..10 55
2..3 5
2..4 9
2..5 14
2..6 20
2..7 27
2..8 35
2..9 44
2..10 54
3..4 7
3..5 12
3..6 18
3..7 25
3..8 33
3..9 42
3..10 52
4..5 9
4..6 15
4..7 22
4..8 30
4..9 39
4..10 49
5..6 11
5..7 18
5..8 26
5..9 35
5..10 45
6..7 13
6..8 21
6..9 30
6..10 40
7..8 15
7..9 24
7..10 34
8..9 17
8..10 27
9..10 19
i: 3 Count: 1 Instances: [[1..2]]
i: 4 Count: 0 Instances: []
i: 5 Count: 1 Instances: [[2..3]]
i: 6 Count: 1 Instances: [[1..3]]
i: 7 Count: 1 Instances: [[3..4]]
i: 8 Count: 0 Instances: []
i: 9 Count: 2 Instances: [[2..4], [4..5]]
i: 10 Count: 1 Instances: [[1..4]]
i: 11 Count: 1 Instances: [[5..6]]
i: 12 Count: 1 Instances: [[3..5]]
i: 13 Count: 1 Instances: [[6..7]]
i: 14 Count: 1 Instances: [[2..5]]
i: 15 Count: 3 Instances: [[1..5], [4..6], [7..8]]
For example I have array with length n=3:
for(int i = 0; i < n; i++) {
array[i] = i;
}
So the cases should be:
1. 0
2. 1
3. 2
4. 0 1
5. 0 2
6. 1 2
7. 0 1 2
So the number of cases should be 7 for n = 3.
In my code:
int n = 3;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
int sum = 0;
for (int i = 0; i < n; i++) {
System.out.println(array[i] + " ");
sum++;
for (int j = i; j < n; j++) {
System.out.print(array[j] + " ");
}
System.out.println();
sum++;
}
System.out.println("sum = " + sum);
Output is:
0
0 1 2
1
1 2
2
2
sum = 6
The number 2 is two times so it is wrong and sum is actually = 5. And I don't get cases
4. 0 1
and
5. 0 2
How to count all possible cases?
Sets, not arrays
The first important observance is that you are not using fixed length arrays here but sets of different lengths.
Take a look at your example. You allow
0
1
2
0, 1
0, 2
1, 2
which are not all of size 3.
Also you don't differentiate between
0, 1
1, 0
so order doesn't matter, like in sets.
Power set
That's why you're actually describing power sets here. For the example set {0, 1, 2} its power set is defined as
P({0, 1, 2}) = {
{}, // empty set
{0},
{1},
{2},
{0, 1},
{0, 2},
{1, 2},
{0, 1, 2}
}
Fortunately there exists an easy closed formula for their size. If n is the size of the input set the size of the power set is
2^n
But they also count the empty set, so you will need to -1 if you don't want that:
2^n - 1
Solution
Thus in Java you could write
int Set<Integer> input = ...
int size = (int) Math.pow(2, input.size()) - 1;
and that's all, you don't need to build the contents manually.
But if you're curious and want to build them, take a look at questions like Obtaining a powerset of a set in Java. It's an implementation of the recursive formula shown at Wikipedia.
So, totally inefficient but also working:
int Set<Integer> input = ...
// Build the power-set using the method from linked question
Set<Set<Integer>> power = powerSet(input);
int size = power.size() - 1;
This question already has answers here:
Big O, how do you calculate/approximate it?
(24 answers)
Closed 5 years ago.
I am trying to learn about time complexity of an algorithm. My professor has pushed it beyond Big O and wants us to be able to derive an algorithm to a mathematical function. I am having a hard time conceptualizing how this is done and was looking for help. In my class notes, a selection sort algorithm was provided (as shown in the code below). The notes asked the following question: "Derive a function f(n) that corresponds to the total number of times that minIndex or any position of nums is modified in the worst case. Now the notes tell me the answer is f(n)= 1/2n^2 + 5/2n + 3. I was wondering if anyone could explain how this occurs.
My professor told us to count the operations in the inner loop and work our way out. so I believe that at worst case in the inner loop the if statement always executes, this would mean we run the loop n-i-1 times, I get these values by taking n (the boundary that the for loop has to be less than and subtracting it by the starting condition (i+1). Then I look at the outer loop and I see it goes from i until it reaches n-1, so it could be written as (n-1)-i or just like the inner loop, n-i-1. Looking further there are three modifications in the outer loop so we get (n-i-1)+3 ( could I write it as (n-i+2)?
The number of modification at the worst case for the inner loop:
n-i-1
The number of modifications at the worst case for the outer loop:
(n-i-1)+3
now I would like to know how do you go from counting the two different modifications done and becoming f(n)= 1/2n^2 + 5/2n + 3.
public static void selectionSort(int[] nums) {
int n = nums.length;
int minIndex;
for(int i = 0; i < n-1; i++) {
//find the index of themin number.
minIndex = i;
for(int j = i+1; j < n; j++) {
if(nums[j] < nums[minIndex]) {
minIndex = j;
}
int temp = nums[i];
nums[i] = nums[minIndex];
nums[minIndex] = temp;
}
}
}
How many times does outer loop run?
n - 1 times.
How many times does inner loop run, for each iteration of outer loop?
From n - 1 times down to 1 time, as outer loop progresses, so on average:
((n - 1) + 1) / 2 = n / 2 times.
So, how many times does inner loop run in total?
(n - 1) * (n / 2) = n^2 / 2 - n / 2 times.
How many times is minIndex modified?
Once per outer loop + once per inner loop:
(n - 1) + (n^2 / 2 - n / 2) = n^2 / 2 + n / 2 - 1 times.
How many times is a position of nums modified?
Twice per inner loop:
2 * (n^2 / 2 - n / 2) = n^2 - n times.
What is total number of modifications?
(n^2 / 2 + n / 2 - 1) + (n^2 - n) = (3*n^2 - n) / 2 - 1 times.
Or 1½n² - ½n - 1
That's not the same answer as you said your notes has, so let's prove it.
First, we add debug printing, i.e. print any modification including a modification number.
public static void selectionSort(int[] nums) {
int mod = 0;
int n = nums.length;
int minIndex;
for(int i = 0; i < n-1; i++) {
//find the index of themin number.
minIndex = i; System.out.printf("%2d: minIndex = %d%n", ++mod, i);
for(int j = i+1; j < n; j++) {
if(nums[j] < nums[minIndex]) {
minIndex = j; System.out.printf("%2d: minIndex = %d%n", ++mod, j);
}
int temp = nums[i];
nums[i] = nums[minIndex]; System.out.printf("%2d: nums[%d] = %d%n", ++mod, i, nums[minIndex]);
nums[minIndex] = temp; System.out.printf("%2d: nums[%d] = %d%n", ++mod, minIndex, temp);
}
}
}
Worst case is sorting an array of descending numbers, so lets try 3 numbers:
int[] nums = { 3, 2, 1 };
selectionSort(nums);
System.out.println(Arrays.toString(nums));
We'd expect (3*n^2 - n) / 2 - 1 = (3*3^2 - 3) / 2 - 1 = 24 / 2 - 1 = 11 modifications.
1: minIndex = 0
2: minIndex = 1
3: nums[0] = 2
4: nums[1] = 3
5: minIndex = 2
6: nums[0] = 1
7: nums[2] = 2
8: minIndex = 1
9: minIndex = 2
10: nums[1] = 2
11: nums[2] = 3
[1, 2, 3]
Yup, 11 modifications.
Lets try 9:
int[] nums = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
(3*n^2 - n) / 2 - 1 = (3*9^2 - 9) / 2 - 1 = 234 / 2 - 1 = 116 modifications.
1: minIndex = 0
2: minIndex = 1
3: nums[0] = 8
4: nums[1] = 9
5: minIndex = 2
6: nums[0] = 7
. . .
111: nums[6] = 7
112: nums[8] = 8
113: minIndex = 7
114: minIndex = 8
115: nums[7] = 8
116: nums[8] = 9
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Yup, 116 modification.
Formula verified by empiric evidence:
f(n) = (3*n^2 - n) / 2 - 1
This is the given question:
Given a non-negative number represented as an array of digits,
add 1 to the number ( increment the number represented by the digits ).
The digits are stored such that the most significant digit is at the head of the list.
Example:
If the vector has [1, 2, 3]
the returned vector should be [1, 2, 4]
as 123 + 1 = 124.
This is my code:
public class Solution {
public ArrayList<Integer> plusOne(ArrayList<Integer> A) {
int carry = 1;
int length = A.size();
ArrayList result = new ArrayList();
for( int i = length - 1; i >=0; i-- ){
int val = A.get(i) + carry;
result.add(0,val % 10);
carry = val / 10;
}
if (carry == 1){
result.add(0,1);
}
for (int j = 0; j < result.size(); j++){
if(result.get(j).equals(0))
result.remove(j);
else
break;
}
return result;
}
}
However, in the test case:
A : [ 0, 6, 0, 6, 4, 8, 8, 1 ]
it says my function returns
6 6 4 8 8 2
while the correct answer is
6 0 6 4 8 8 2
I have no idea what is wrong with my code.
Thanks!
if(result.get(j).equals(0))
result.remove(j);
else
break;
This will fail if every other index contains a 0. Here's what happens:
0 6 0 6 4 8 8 2
^ (j = 0)
The 0 will be removed, and j is incremented by one.
6 0 6 4 8 8 2
^ (j = 1)
Then this 0 is removed as well, skipping the first 6 in your array. To fix this, change the snippet to:
if(result.get(j).equals(0))
result.remove(j--);
else
break;
This compensates for when an index is removed so that j will not skip the number immediately after any removed 0s.
Check out a similar question at Looping through and arraylist and removing elements at specified index
simpler to do just
while (!result.isEmpty() && result.get(0).equals(0)) {
result.remove(0);
}
This will keep removing the left most 0 until there is no more left most zero to be deleted.
Your last for loop is removing 0 from your result ArrayList<Integer>. After removing that loop, you will get perfect output
public static ArrayList<Integer> plusOne(ArrayList<Integer> A) {
int carry = 1;
int length = A.size();
ArrayList result = new ArrayList();
for (int i = length - 1; i >= 0; i--) {
int val = A.get(i) + carry; //2 8
result.add(0, val % 10); // 2 8
carry = val / 10;
}
if (carry == 1) {
result.add(0, 1);
}
// for (int j = 0; j < result.size(); j++) {
// if (result.get(j).equals(0))
// result.remove(j);
// else
// break;
// }
for (boolean isZero = true; isZero; ) {
isZero = result.get(0).equals(0);
if(isZero)
result.remove(0);
}
return result;
}