This question already has answers here:
Pascal's triangle positioning
(5 answers)
Closed 1 year ago.
Java beginner here! As part of practicing programming, I've run into Pascal's triangle. I tried to implement a solution where the triangle is printed like so:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
...
So roughly right-sided. My solution though runs into multiple errors, and although I would appreciate help with that, I would primarily like to know if I am thinking correctly with my solution. (For some functions I am using a custom library)
public static void main(String[] args) {
int input = readInt("Enter triangle size, n = ");
array = new int[input][input];
for (int i = 0; i < input; i++) { // rows
for (int j = 0; j < i + 1; j++) { // columns
if (i = 0) {
array[i][0] = 1;
} else if (i != 0 && i == j) {
array[i][j] = 1;
} else {
array[i][j] = array[i - 1][j] + array[i - 1][j - 1];
}
}
}
// print out only the lower triangle of the matrix
for (int i = 0; i < input; i++) {
for (int j = 0; j < input; j++) {
if (i <= j) {
System.out.println("%d ", array[i][j]);
}
}
}
}
You were on the right track. Here's how I implemented it:
Scanner sc = new Scanner(System.in);
System.out.print("Enter triangle size, n = ");
int n = sc.nextInt();
sc.close();
//This will be a jagged array
int[][] array = new int[n][0];
for (int i = 0; i < n; i++) {
//Add the next level (it's empty at the start)
array[i] = new int[i + 1];
for (int j = 0; j <= i; j++) {
//At the ends, it's just 1
if (j == 0 || j == i) {
array[i][j] = 1;
} else { //The middle
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
}
}
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j <= i; j++) {
//printf is what you use to do formatting
System.out.printf("%d ", array[i][j]);
}
//Without this, everything's on the same line
System.out.println();
}
Your else part was correct, but you didn't check if j equaled 0 before that. Instead of setting the current element to 1 when i was 0 or when i equaled j, you should have done it when j was 0 or when i equaled j. Because of this mistake, in later rows where i was not 0, but j was, you tried to access array[i - 1][j - 1], which was basically array[i - 1][-1], causing an IndexOutOfBoundsException.
I also made a jagged array instead of an even matrix because it made more sense that way, but it shouldn't matter much.
Also, this wasn't an error, but you did else if (i!=0 && i==j) The i != 0 part is unnecessary because you checked previously if i == 0.
Link to repl.it
Related
Two players take turns choosing one of the outer coins. At the end we calculate the difference between the score two players get, given that they play optimally. for example the list{4,3,2,1},
the optimal sequence would be 4, 3, 2, 1. then i will get 4+2 = 6 scores and the opponent 4 scores.
Now i have developed an algorithm as follow:
My Job is to print the scores out, and also the optimal sequence in index. so in the array {4,3,2,1} the optimal sequence would be 0,1,2,3.
The maximum Runtime and Memory should not exceed n^2.
Therefore I implemented the above algorithm with bottom up approach,which means in an i*j table, according to my algorithm, subproblems are solved one by one until the only main problem, which locates at the top right corner(where i =0 and j = n-1). It works calculating the scores, but i have no idea how to trace the optimal sequence during runtime, since when I calculate subproblems by subproblems, only the score will be save and used in the next problem, while the sequence, which led to the final result, is hard to trace back.
I tried to create Pairs or multidimensional ArrayList to record the sequences and their corresponding memo[i][j]...... Well, they worked, but the memory needed would then be greater than n^2 and this is not allowed in my task.
So, does anymore have a better idea that does not require that much memory space?
Any help would be appreciated, cheers!
My code:
public int maxGain(int[] values) {
int n = values.length;
int [][] memo = new int[n][n];
for (int i = 0; i < n; i++)
memo[i][i] = values[i];
for (int i = 0, j = 1; j < n; i++, j++)
memo[i][j] = Math.max(values[i], values[j]);
for (int k = 2; k < n; k++) {
for (int i = 0, j = k; j < n; i++, j++) {
int a = values[i] + Math.min(memo[i + 2][j], memo[i + 1][j - 1]);
int b = values[j] + Math.min(memo[i + 1][j - 1], memo[i][j - 2]);
memo[i][j] = Math.max(a, b);
}
}
return memo[0][n - 1];
}
I guess your question is similar to Predict the Winner of LeetCode (486) with some minor changes that you would want to make:
Java
class Solution {
public boolean maxGain(int[] nums) {
int length = nums.length;
int[][] dp = new int[length][length];
for (int i = 0; i < length; i++)
dp[i][i] = nums[i];
for (int l = 1; l < length; l++)
for (int i = 0; i < length - l; i++) {
int j = i + l;
dp[i][j] = Math.max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
}
return dp[0][length - 1] > -1;
}
}
Python
class Solution:
def max_gain(self, nums):
length = len(nums)
memo = [[-1 for _ in range(length)] for _ in range(length)]
#functools.lru_cache(None)
def f():
def helper(nums, i, j):
if i > j:
return 0
if i == j:
return nums[i]
if memo[i][j] != -1:
return memo[i][j]
cur = max(nums[i] + min(helper(nums, i + 2, j), helper(nums, i + 1, j - 1)),
nums[j] + min(helper(nums, i, j - 2), helper(nums, i + 1, j - 1)))
memo[i][j] = cur
return cur
score = helper(nums, 0, length - 1)
total = sum(nums)
return 2 * score >= total
return f()
O(N) Memory
The space complexity might be an order of N for the second solution provided in this link:
class Solution {
public boolean maxGain(int[] nums) {
if (nums == null)
return true;
int length = nums.length;
int[] dp = new int[length];
for (int i = length - 1; i >= 0; i--) {
for (int j = i; j < length; j++) {
if (i == j)
dp[i] = nums[i];
else
dp[j] = Math.max(nums[i] - dp[j], nums[j] - dp[j - 1]);
}
}
return dp[length - 1] > -1;
}
}
Reference
Most optimal solutions are here in the discussion board
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 have to check if a sequence of any numbers are equals. The user will submit a sequence, and if, the numbers repeat in sequence, he won some points.
And the sequence to win the points it's a sequence of three. For example:
1 3 4 4 4 5
He won the points because he inputted a sequence of 3 numbers 4.
The sequence of numbers it's on a Vector. The size of the vector, It's given by the user too.
for (int i = 0; i < M.length; i++) {
if (M[i] == M[i + 1] && M[i + 1] == M[i+2]) {
if (L[i] == L[i + 1] && L[i + 1] == L[i + 2]) {
ValuePoint = 0;
} else {
PExtraM = i;
ValuePoint = 30;
}
Scanner sc1 = new Scanner(System.in);
R = sc1.nextInt();
int M[] = new int[R];
int L[] = new int[R];
for (int i = 0; i < M.length; i++) {
M[i] = sc1.nextInt();
}
for (int i = 0; i < L.length; i++) {
L[i] = sc1.nextInt();
}
//The problem It's here ************************************
for (int i = 0; i < M.length; i++) {
if (M[i] == M[i + 1] && M[i + 1] == M[i+2]) {
if (L[i] == L[i + 1] && L[i + 1] == L[i + 2]) {
ValuePoint = 0;
} else {
PExtraM = i;
ValuePoint = 30;
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at maratona.Maratona2.main(Maratona2.java:37)
Java Result: 1
i < M.length
Now let's assume the length of the Vector you are saying is 5 ok?
Now my loop will run till i is less than 5, right?
Now go to your next code :
if (M[i] == M[i + 1] && M[i + 1] == M[i+2])
Let's take the value of i as
4 (suppose)
which is in fact less than 5 and the loop condition satisfies.
But see the next code, it becomes
M[4]==M[5]&& ==M[6]
Obviously since the length of the given Vector is 5, my last element's index will be 4.
So after that **5 & 6 ** will show null only.
That's why it's saying ArrayIndexOutOfBounds Exception error at 5.
Hope this helps!
your loop variable i must stop at m.length-3
(i <m. length-2)
to have i+1=m.length-2 and i+2=m.length-1
but in your case you are trying to access i+1=m.length and i+2= m.length+1 both are out of bounds on the last two iterations
As the others already said, u r overshooting the boundaries of your array. You need to stop the loop 2 earlier to prevent.
You possably want to use something like that:
int sequenceLength = 3;
for (int i = 0; i <= M.length - sequenceLength; i++) {
boolean correct = true;
for (int j = 0; j < sequenceLength && (correct = (M[i] == M[j+i])); j++);
if (correct){
ValuePoint = 0;
} else {
PExtraM = i;
ValuePoint = 30;
break;
}
}
I'm trying to check the neighboring values of each element in a 2D array but am getting an IndexOutOfBoundsException when I reach the sides of the array or a corner. For example if my array is:
|2|4|2|7|8|
|8|1|0|5|6|
|0|3|1|5|2|
|1|9|7|2|0|
I know that all the neighbors of 8 are 7,5 and 6, but my if statements don't check the bounds properly. The code I have for this is:
int numOfRows = imageArray.length;
int numOfColumns = imageArray[0].length;
for(int i = 0; i < numOfRows; i++)
for(int j = 0; j < numOfColumns; j++)
if((j+1) < numOfColumns-1)
if((i+1) < numOfRows-1)
if((j-1) > 0 )
if((i-1) > 0 )
if((i+1) < numOfColumns-1 && (j+1) < numOfRows-1)
if((i-1) >= 0 && (j-1) >= 0)
if((i+1) < numOfColumns-1 && (j-1) >= 0)
if((i-1) >= 0 && (j+1) < numOfRows-1)
I've been working on this for a while and have gone through many different techniques to solve this. Any help would be great. Thanks.
If you're trying to get all the neighbor cells and do something with them, for example add them, then you need to do some sort of bounds checking, for example something modified from this could work:
for (int i = 0; i < numOfRows; i++) {
for (int j = 0; j < numOfCols; j++) {
// check all bounds out of range:
int iMin = Math.max(0, i - 1);
int iMax = Math.min(numOfRows - 1, i + 1);
int jMin = Math.max(0, j - 1);
int jMax = Math.min(numOfCols - 1, j + 1);
// loop through the above numbers safely
for (int innerI = iMin; innerI <= iMax; innerI++) {
for (int innerJ = jMin; innerJ <= jMax; innerJ++) {
if (i != innerI && j != innerJ) {
// do what needs to be done
}
}
}
}
}
Caveat: code has not been compiled nor tested and is mainly to show you the idea of what can be done rather than a copy-paste solution
I have been working on Magic Square formation, after reading through the algo, I found out there are certain set of rules to be followed while forming the MagicSquare.
The algo which I'm following is :
The magic constant will always be equal to n(n^2 + 1)/2, where n is the dimension given.
Numbers which magicSquare consists will always be equals 1 to n*n.
For the first element that is 1, will always be in the position (n/2, n-1).
Other elements will be placed like (i--,j++)
The condition to be put through for placing an elements are :
a) If i < 0, then i = n-1.
b) If j == n, then j = 0.
c) This is a special case, if i < 0 and j=n happens at the same time, then i = 0, j = n-2.
d) If the position is already occupied by some other element, then i++, j = j-2.
Then input the element inside the magicSquare based upon the conditions.
Based upon the above algo, I have written down a code, and due to some reason I'm getting
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Main.generateMagicSquare(Main.java:25)
at Main.main(Main.java:58)
This is weird. I have checked, and feels like it is safe to use the code to get the desired result, but I don't know where I'm going wrong.
Code
static void generateMagicSquare(int n){
int[][] magicSquare = new int[n][n];
//initialising for pos of the elem 1
int i = n/2, j = n-1;
magicSquare[i][j] = 1;
//the element consist by the magic square will always be equal to 1 to n*n
for(int num=2; num <= n*n; num++){
//it must go like this, for any other element
i--; j++;
// if the element is already present
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
if(i < 0)
i = n-1;
if(j == n)
j = 0;
if(i < 0 && j == n){
i = 0;
j = n-2;
}
}
magicSquare[i][j] = num;
}
for(int k=0; k<n; k++){
for(int l=0; l<n; l++){
System.out.print(magicSquare[k][l] + " ");
}
System.out.println();
}
}
Any help would be appreciated. Thanks. Since I could have copied and pasted the code from internet, but I want to learn it in my way, and your help would help me achieve what I want. :)
EDITS
After reading through the exception, I made some amendments in my code, but still some of the result didn't come upto the mark.
Here is my updated code =======>
static void generateMagicSquare(int n){
int[][] magicSquare = new int[n][n];
//initialising for pos of the elem 1
int i = n/2, j = n-1;
magicSquare[i][j] = 1;
//the element consist by the magic square will always be equal to 1 to n*n
for(int num=2; num <= n*n; num++){
//it must go like this, for any other element
i--; j++;
if(i < 0){
i = n-1;
}
if(j == n){
j = 0;
}
if(i < 0 && j == n){
i = 0;
j = n-2;
}
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
magicSquare[i][j] = num;
}
}
for(int k=0; k<n; k++){
for(int l=0; l<n; l++){
System.out.print(magicSquare[k][l] + " ");
}
System.out.println();
}
}
I get this output :
2 0 6
9 5 1
7 3 0
Still not the right answer to follow.
This line throws the error:
if(magicSquare[i][j] != 0)
and the problem is that the array magicSquare is initialized as:
int[][] magicSquare = new int[n][n];
meaning that it has n columns with indexes from 0 to n - 1 (indexes are zero based).
The variable j is initialized as
j = n-1;
and later this line:
j++;
makes j equal to n
so when you access magicSquare[i][j] you are trying to access magicSquare[i][n] which does not exist.
The index of an array is an integer value that has value in interval [0, n-1], where n is the size of the array. If a request for a negative or an index greater than or equal to size of array is made, then the JAVA throws a ArrayIndexOutOfBounds Exception. You have to check the value of i and j before using it in array. You can use the below code :
for(int num=2; num <= n*n; num++){
i--; j++;
//Here We have to check the value of i and j i.e. it should less than or equal to the length of array.
if((i <= magicSquare[0].length-1 && j <= magicSquare[0].length-1))
{
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
if(i < 0)
i = n-1;
if(j == n)
j = 0;
if(i < 0 && j == n){
i = 0;
j = n-2;
}
}
magicSquare[i][j] = num;
}
}
For understanding ArrayIndexOutOfBoundsException, Please visit :
https://www.geeksforgeeks.org/understanding-array-indexoutofbounds-exception-in-java/
I am trying to make my code print out the Asterisk in the image, you see below. The Asterisk are align to the right and they have blank spaces under them. I can't figure out, how to make it go to the right. Here is my code:
public class Assn4 {
public static void main(String[] args) {
for (int i = 0; i <= 3; i++) {
for (int j = 0; j <= i; j++) {
System.out.print("*");
}
for (int x = 0; x <= 1; x++) {
System.out.println(" ");
}
for (int j = 0; j <= i; j++) {
System.out.print("*");
}
}
System.out.println();
}
}
Matrix problems are really helpful to understand loops..
Understanding of your problem:
1) First, printing star at the end- That means your first loop should be in decreasing order
for(int i =7;i>=0; i+=i-2)
2) Printing star in increasing order- That means your second loop should be in increasing order
for(int j =0;j<=7; j++)
Complete code:
for(int i =7;i>=0; i=i-2){ // i=i-2 because *s are getting incremented by 2
for(int j =0;j<=7; j++){
if(j>=i){ // if j >= i then print * else space(" ")
System.out.print("*");
}
else{
System.out.print(" ");
}
}
System.out.println();// a new line just after printing *s
}
Starting loops with 1 can sometimes help you visualize better.
int stopAt = 7;
for (int i = 1; i <= stopAt ; i += 2) {
for (int j = 1; j <= stopAt; j++) {
System.out.print(j <= stopAt - i ? " " : "*");
}
System.out.println();
}
Notice, how each row prints an odd number of *s ending at the line with 7. So, you start with i at 1 and go through 3 1+2, 5 3+2, and then stopAt 7 5+2.
The nested for loop has to print 7 characters always to make sure *s appear right aligned. So, the loop runs from 1 to 7.
Here the complete code:
for(int i = 0; i < 8; i++){
if( i%2 != 0){
for(int x = 0; x < i; x++){
System.out.print("*");
}
}else{
System.out.println();
}
}