Problem: Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
Example
Given input array A = [1,1,2],
Your function should return length = 2, and A is now [1,2].
My solution:
public int removeDuplicates(int[] nums) {
if(nums.length == 0) {
return 0;
}
int size = 0;
for(int i = 0; i < nums.length; i++) {
if((i + 1) <= nums.length && (nums[i] != nums[i + 1])) {
nums[size] = nums[i];
size++;
}
}
}
The problem that I am running into is a ArrayIndexOutOfBoundsException in the second if statement:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 at Solution.removeDuplicates(Solution.java:15) at Main.main(Main.java:10)
I do not understand why because I am checking if i+1 <= the length of the array, which should prevent the overflow error.
You should change the "i + 1 <= nums.length" to "i + 1 < nums.length". When your variable (i) is at the end of loop (i + 1) will be out of array. For example A = [1,1,2] and the length is 3. In the for loop i will be 2 and i+1 will be 3 so nums[3] wil be out of bound.
for(int i = 0; i < nums.length; i++) {
if((i + 1) < nums.length && (nums[i] != nums[i + 1])) {
nums[size] = nums[i];
size++;
}
else if(i + 1 == nums.length)
num[size] = nums[i];
}
Related
I'm supposed to write a program that reads an array of ints and outputs the number of "triples" in the array.
A "triple" is three consecutive ints in increasing order differing by 1 (i.e. 3,4,5 is a triple, but 5,4,3 and 2,4,6 are not).
How do I check for the "triples"?
Current Code:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
int iterator = 0;
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
} for(int j =0; j < size; j++){
iterator++;
}
}
}
The following code loops through the entire array of integers. Inside of the loop it is checked if the third integer exists inside of the array ((i + 2) < array.Length) and the other 2 conditions are all about whether value1 is the same as the value2 decreased by 1 (array[i] == array[i + 1] - 1 and array[i + 1] == array[i + 2] - 1):
for (int i = 0; i < array.Length; i++)
{
if((i + 2) < array.Length && array[i] == array[i + 1] - 1 && array[i + 1] == array[i + 2] - 1)
System.out.println("Three values at indexes" + i + " " + (i + 1) + " and " + (i + 2) + " are a triple");
}
The code below is C# and sadly not compatible to Java that easily, I'll just leave that here for anyone who wants to know how its handled in C# (the vt variable is a so called ValueTriple):
(int, int, int) vt;
for (var i = 0; i < array.Length; i++)
{
if (i + 2 >= array.Length) continue;
vt = (array[i], array[i + 1], array[i + 2]);
if (vt.Item1 == vt.Item2 - 1 && vt.Item2 == vt.Item3 - 1)
Console.WriteLine($"Three values at indexes {i}, {i + 1} and {i + 2} (Values: {array[i]}, {array[i + 1]}, {array[i + 2]}) are a triple");
}
You may try following code
import java.util.Scanner;
public class Triplet {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
}
Integer counter = 0;
for(int i = 0; i < size-2; i++) {
if(array[i] == array[i+1] - 1 && array[i] == array[i+2] - 2) { //checking if three consecutive ints in increasing order differing by 1
counter++;
}
}
System.out.println(counter);
}
}
Hope this will help.
A method to find out the number of triplets could look like this. You then just have to call the method depending how your input is obtained and you wish to present the result.
public static int getNumberOfTriplets(int[] toBeChecked) {
int numberOfTriplets = 0;
int nextIndex = 0;
while (nextIndex < toBeChecked.length - 2) {
int first = toBeChecked[nextIndex];
int second = toBeChecked[nextIndex + 1];
int third = toBeChecked[nextIndex + 2];
if ((first + 1 == second) && (second + 1 == third)) {
numberOfTriplets++;
}
nextIndex++;
}
return numberOfTriplets;
}
Regardless of allowing the numbers to be in more than one triplet, the answer is fairly similar in how I would personally approach it:
//determines if the input sequence is consecutive
public boolean isConsecutive(int... values) {
return IntStream.range(1, values.length)
.allMatch(i -> values[i] == values[i - 1] + 1);
}
public int countTriples(int[] input, boolean uniques) {
if (input.length < 3) {
return 0;
}
int back = 0;
for(int i = 2; i < input.length; i++) {
if (isConsecutive(input[i - 2], input[i - 1], input [i]) {
back++;
if (uniques) { //whether to disallow overlapping numbers
i += 2; //triple found, ignore the used numbers if needed
}
}
}
return back;
}
Then in calling it:
Int[] input = new int[] {1, 2, 3, 5, 6, 7, 8};
countTriples(input, true); //3
countTriples(input, false); //2
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/
In this case, I want to add two numbers in this array in to obtain a specific sum when added, let’s say, 4. I also want to output what indices are being added in order to obtain that specific sum, just to see the inner workings of my code. What am I doing wrong?
public static int addingNumbers(int[] a) {
int i1 = 0, i2 = 0;
for(int i = 0, j = i + 1; i < a.length && j < a.length; i++, j++) {
if(a[i] + a[j] == 4) { // index 0 and index 2 when added gives you a sum 4
i1 = i;
i2 = j;
}
}
System.out.println("The indices are " + i1 + " and " + i2);
return i1;
}
public static void main(String args[]) {
int[] a = {1, 2, 3, 4, 5, 6};
System.out.println(addingNumbers(a));
}
The error you are making is using only one loop that iterates over the array once:
for(int i = 0, j = i + 1; i < a.length && j < a.length; i++, j++) {
In your loop you are setting i to 0 and j to 1, then you increment them with every step. So you are only comparing adjacent places in your array:
iteration: a[0] + a[1]
iteration: a[1] + a[2]
iteration: a[2] + a[3]
etc. pp
Since your array doesn't have two adjacent elements that sum up to 4 your if(a[i] + a[j] == 4) will never be entered and i1, i2 will still be 0 when the loop is finished.
To compare every array element with each other you should use 2 nested loops:
public static int addingNumbers(int[] a) {
int i1 = -1, i2 = -1;
for(int i = 0; i < a.length ; i++) {
for(int j = i+1; j < a.length ; j++) {
if(a[i] + a[j] == 4) { // index 0 and index 2 when added gives you a sum 4
i1 = i;
i2 = j;
}
}
}
if(i1>=0 && i2 >=0) {
System.out.println("The indices are " + i1 + " and " + i2);
}
return i1;
}
Note that this will only print out the last detected 2 indices that add up to 4. If you want to be able to detect multiple possible solutions and print them out could for example move the System.out.println into the if block.
It can never be == 4 because 1+2=3 then 2+3=5. So it does nothing.
There is a logic error in your code. The sum you are checking in your code is never for.
I added some debug output for easy checking:
public static int addingNumbers(int[] a) {
int i1 = 0, i2 = 0;
for(int i = 0, j = i + 1; i < a.length && j < a.length; i++, j++) {
int sum = a[i] + a[j];
System.out.println(sum);
if(sum == 4) { // index 0 and index 2 when added gives you a sum 4
i1 = i;
i2 = j;
}
}
System.out.println("The indices are " + i1 + " and " + i2);
return i1;
}
Output is: 3
5
7
9
11
The indices are 0 and 0
0
this algorithm will never be able to add a[0] to a[2], be cause when you put j=i+1 it will always be 0+1 then 1+2 ... The sum of tow adjacent numbers is never pair.
An other matter is the condition to stop your loop must be j < a.length-1
try to explain more of what you want from your algorithm.
Are you over complicating this on purpose?
Trying to figure out your intention for this task.
Why don't you just do (this is pseudo):
for length of i {
if (a[i] + a[i+1] == 4) {
System.out.println("The indices are " + a[i] + " and " + a[i+1]);
}
}
I am trying to solve Sherlock and Array algorithm task. I have array and i need to find element in the array such that the sum of the elements on its left side is equal to the elements of it's right side, like i mentioned in the title. My algorithm works for small arrays, but for big arrays it is too slove, what can i do to improve it's speed ?
Just to mention. This algorithm dont accept arrays of size 1 and 2.
public static boolean isSherlock(int arr[])
{
int length = arr.length;
int leftSum = 0;
int rightSum = 0;
for(int i=0; i<length-1; i++)
{
leftSum = 0;
rightSum = 0;
// Left sum for index i
for(int j=0; j<i; j++)
leftSum+=arr[j];
// Right sum for index i
for(int j=i+1; j<length && leftSum != 0; j++)
rightSum+=arr[j];
if(leftSum == rightSum && leftSum != 0 && rightSum != 0)
{
return true;
}
}
return false;
}
This is O(N^2) is there any way to do it in O(n) ?
The linear solution is pretty easy.
Calculate the sum of all elements in the array A. Of course, it can be done in linear time. Call it S.
Then iterate over all elements and store two sums: the sum of all elements which lie to the left on the current element and the sum of all elements which lie to the right on the current elements. Call them L and R.
For the first element A[0]:
L = 0
R = S - A[0]
When you move to A[i] you recalculate L and R:
L = L + A[i - 1]
R = R - A[i]
If L == R then the current elements is the answer.
At, first store the sum and then use that sum. Here is the code below:
public static boolean isSherlock(int arr[])
{
int length = arr.length;
int sum = 0;
for(int i=0; i<length; ++i)
sum += arr[i];
int rightSum = sum-arr[0];
int leftSum = 0;
for(int i=0; i<length-1; ++i){
if(leftSum == rightSum)
return true;
leftSum += arr[i];
rightSum -= arr[i+1];
}
if (leftSum == rightSum)
return true;
return false;
}
You could save the left sum and rigth sum computed at previous step as follows:
int sumLeftStepI=0;
int sumRigthStepI = Arrays.stream(a).sum() - a[0];
for (int i=0; i<a.length;i++){
if(sumLeftStepI==sumRigthStepI){
System.out.println("found element at position a["+i+"]");
}
if(i<a.length-1){
sumLeftStepI+=a[i];
sumRigthStepI-=a[i+1];
}
}
In this way the complexity should be O(n).
try this
public static boolean isSherlock(int arr[])
{
if (arr.length > 2) {
int i = 1;
for (; i < arr.length - 1; i++) {
int k = 0;
int rhs = arr[i + 1];
int lhs = arr[i - 1];
int j = arr.length - 1;
// **In single iteration it is suming from left as well as from right**
while (k < i - 1 && j > i + 1) {
rhs += arr[j--];
lhs += arr[k++];
}
// **************
// If any elements remain
while (k < i - 1)
lhs += arr[k++];
while (j > i + 1)
rhs += arr[j--];
// compare
if (rhs == lhs && lhs != 0 && rhs != 0) {
return true;
}
}
}
return false;
}
No need to create a separate variable for sum. Assign the sum value to the right or the left.
This is the most efficient code that I came up with.
Also it is obvious that for array of length less than 3, result would
always be false.
private static boolean balanceIntArrray(int[] nums) {
int length = nums.length;
if (length < 3) {
return false;
}
int left = nums[0];
int right = 0;
for (int i = 2; i < nums.length; i++) {
right += nums[i];
}
for (int i = 1; i < nums.length - 1; i++) {
if (left == right) {
return true;
}
left += nums[i];
right -= nums[i + 1];
}
return (left == right);
}
I want to write a program that reads a matrix of positive int with the format txt (the matrix can be of any size). (I read the matrix from the console).
The program looks for a location in the matrix such that if a knight is positioned at that location, all possible moves will land the knight on elements which have the same value and it must have at least 2 options. The program prints the result. for example, the black places are where the knight can move to.
This is the code I wrote. the problem is that i'm getting: "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Knights.main(Knights.java:23)", I know it has a problem with the first row (there is no backwards value in the start of the matrix) but I don't know how can I fix it.
public static void main (String[] args) {
String size = StdIn.readLine();
int counter = 0;
int matrixSize = Integer.parseInt(size);
int [][] matrix = new int [matrixSize+1][matrixSize+1];
for (int i=0; i <= matrixSize-1; i++) {
for (int j=0; j <= matrixSize-1; j++) {
if ((matrix[i][j]) > 0)
matrix[i][j] = StdIn.readInt();
}
}
for (int k=0; k <= matrixSize-2; k++) {
for (int l=0; l <= matrixSize-2; l++) {
if (matrix[k-1][l+2] == matrix[k+1][l+2]) {
counter +=1;
StdOut.println(counter); }
else if (matrix[k-1][l+2] == matrix[k+1][l-2]) {
counter +=1;
StdOut.println(counter); }
if (counter>=2)
StdOut.println("location "+ matrix[k][l] + "is surrounded by the number " +matrix[k+1][l-2]);
}
}
if (counter < 2)
StdOut.println("no surrender by any number");
}
}
I would add an extra test here to check if k-1 is greater than 0.
As && is a short-circuit operator, the second expression is not tested if the first is false and can not throw an exception.
Solution
if (k - 1 > 0 && matrix[k - 1][l + 2] == matrix[k + 1][l + 2]) {
counter += 1;
StdOut.println(counter);
} else if (k - 1 > 0 && matrix[k - 1][l + 2] == matrix[k + 1][l - 2]) {
counter += 1;
StdOut.println(counter);
}