Leetcode : Remove Duplicates from Sorted Array - java

Why this code is not accepted by Leetcode compiler?
My program is running in netbeans. but leetcode compiler is not accepting it.
Here is my code:
import java.util.Arrays;
public class RemoveDuplicateFromArray {
public static int[] removeDuplicates(int[] nums) {
int temp, count = 0 ,l = 0;
temp = nums[0];
for(int i = 1; i < nums.length - (1 + l); i++ ) {
if(temp == nums[i]) {
count = count + 1;
for(int j = i; j < nums.length - count; j++){
nums[j] = nums[j+1];
}
i = i - 1;
} else {
temp = nums[i];
i = i ;
}
l = count;
}
nums = Arrays.copyOfRange(nums, 0, nums.length-count);
if(nums.length == 2){
if(nums[0] == nums[1]){
nums = Arrays.copyOfRange(nums, 0, nums.length-1);
}
}
return nums;
}
Here is my main mathod:
public static void main(String[] args) {
int[] nums = new int[] {1,1,1}; // showing error here.
System.err.println("nums lenght: " +nums.length);
int new_nums[] = removeDuplicates(nums);
for(int i : new_nums) {
System.err.print(i + " ");
}
}
}
The error is :
incompatible types: int[] cannot be converted to int.

I expect leetcode is having trouble with this line:
int new_nums[] = removeDuplicates(nums);
This isn't the typical way to define an integer array (this is the C style). Java does support the syntax, but it's a little arcane. See this answer for more detail.
Try this instead:
int[] new_nums = removeDuplicates(nums);
Just tried this on LeetCode, seems to work:

I would do it a bit like this myself:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
int[] nums = new int[]{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 0, 0, 0, 0};
System.out.println("nums lenght: " + nums.length);
int[] new_nums = removeDuplicates(nums);
for (int i : new_nums) {
System.out.print(i + " ");
}
}
public static int[] removeDuplicates(int[] nums) {
List<Integer> found = new ArrayList();
for (int i = 1; i < nums.length; i++) {
if (!found.contains(nums[i])) {
found.add(nums[i]);
}
}
int[] ret = new int[found.size()];
for(int i = 0; i < found.size(); i++){
ret[i] = found.get(i);
}
return ret;
}
}

public class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
int i = 0;
int j = 1;
if (n <= 1) {
return n;
}
while (j <= n - 1) {
if (nums[i] != nums[j]) {
nums[i + 1] = nums[j];
i++;
}
j++;
}
return i + 1;
}
}
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
class SolutionTest {
#Test
void removeDuplicates() {
int[] array = new int[] {1, 1, 2};
int end = new Solution().removeDuplicates(array);
assertThat(Arrays.toString(Arrays.copyOfRange(array, 0, end)), equalTo("[1, 2]"));
}
}

Related

26. Remove Duplicates from Sorted Array - Java

Question : Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
What exactly does the return statement do here. What does return i + 1 mean here ?
The return i + 1 is returning how many unique integers are there. I believe this is a Leetcode problem, and since its in place, the int[] is passed in by reference, Leetcode wants to know how many numbers to check (you're supposed to put the unique numbers in the first i + 1 spots).
If you look at the question, it says:
Which means that you return the length of the array.
So, if you have the array [1,1,2,3,4,4], you would turn that into [1,2,3,4,...], where the ... is the rest of the array. However, you return 4 because the length of the new array should be 4.
Hope this clears things up for you!
Your question has been already answered here; in addition to that, we can also start from zero and remove the first if statement:
Test with a b.java file:
import java.util.*;
class Solution {
public static final int removeDuplicates(
final int[] nums
) {
int i = 0;
for (int num : nums)
if (i == 0 || num > nums[i - 1]) {
nums[i++] = num;
}
return i;
}
}
class b {
public static void main(String[] args) {
System.out.println(new Solution().removeDuplicates(new int[] { 1, 1, 2}));
System.out.println(new Solution().removeDuplicates(new int[] { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4}));
}
}
prints
2
5
I tried in this easy way. Here Time complexity is O(n) and space
complexity: O(1).
static int removeDuplicates(int[] nums){
if(nums.length == 0) {
return 0;
}
int value = nums[0];
int lastIndex = 0;
int count = 1;
for (int i = 1; i < nums.length; i++) {
if(nums[i] > value) {
value = nums[i];
lastIndex = lastIndex+1;
nums[lastIndex] = value;
count++;
}
}
return count;
}
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0 || n == 1)
return n;
int j = 0;
for (int i=0; i<n-1; i++)
if (nums[i]!= nums[i+1])
nums[j++] = nums[i];
nums[j++]=nums[n-1];
return j;
}
}
public class RemoveDuplicateSortedArray {
//Remove Duplicates from Sorted Array
public static void main(String[] args) {
int[] intArray = new int[]{0, 0, 1, 1, 1, 2, 2, 3, 3, 4};
int count = extracted(intArray);
for (int i = 0; i < count; i++) {
System.out.println(intArray[i]);
}
}
private static int extracted(int[] intArray) {
int size = intArray.length;
int count = 1;
if (size == 1) {
return 1;
} else if (size == 2) {
if (intArray[0] == intArray[1]) {
return 1;
} else {
return 2;
}
} else {
for (int i = 0, j = i + 1; j < size; j++) {
if (intArray[i] < intArray[j]) {
i++;
intArray[i] = intArray[j];
count++;
}
}
return count;
}
}
}

How to replace recursion in my code on Java?

This code calculates the number of permutations for four points by 3 (no repetitions).
Arranged with recursion, but this is awkward for me.
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(0,0, points);
}
static void p1(int nowPosition, int sizeArray, int[] points) {
if (nowPosition == POINTS_ON_LINE) {
System.out.println("Output:");
System.out.println(Arrays.toString(temp));
} else {
for(int i = sizeArray + 1; i <= TOTAL_POINTS; i++) {
temp[nowPosition] = points[i-1];
p1(nowPosition + 1, i, points);
}
}
}
}
Output:
no repetitions:
Output:
[1, 2, 3]
Output:
[1, 2, 4]
Output:
[1, 3, 4]
Output:
[2, 3, 4]
It is necessary to get rid of the recursive method call p1.
I tried to do so:
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(points);
}
static void p1(int[] points) {
int sizeArray = points.length;
for(int i = sizeArray + 1; i < TOTAL_POINTS; i++, sizeArray = i) {
int nowPosition = 0;
if(nowPosition == POINTS_ON_LINE) {
System.out.println("Output: " + Arrays.toString(temp));
} else {
temp[nowPosition] = points[i-1];
nowPosition++;
}
}
}
}
Result - Output on console - empty.
It didn't work for me.
How to replace recursion?
Method # 1 (thanks for the suggested option - #deadshot)
package com.company;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int base) {
int SIZE_ARRAY = arr.length;
List<Integer> indices = IntStream.range(0, base).boxed().collect(Collectors.toList());
for(Integer i : indices) {
System.out.println("- " + i);
}
if (base < SIZE_ARRAY) {
System.out.println("first");
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
boolean flag;
int i;
while (true) {
flag = false;
for (i = base - 1; i >= 0; i--)
if (indices.get(i) != i + SIZE_ARRAY - base) {
flag = true;
break;
}
if (!flag)
return;
indices.set(i, indices.get(i) + 1);
for (int j = i + 1; j < base; j++)
indices.set(j, indices.get(j - 1) + 1);
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
for(Integer x : indices) {
System.out.println("- " + x);
}
}
}
}
}
I have used python itertools.combinations code as reference to implement the method.
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int r) {
int n = arr.length, i;
int[] indices = new int[r];
for (i = 0; i < r; i++)
indices[i] = i;
if (r < n) {
for (int idx : indices)
temp[idx] = arr[idx];
System.out.println(Arrays.toString(temp));
boolean flag;
while (true) {
flag = false;
for (i = r - 1; i >= 0; i--)
if (indices[i] != i + n - r) {
flag = true;
break;
}
if (!flag)
return;
indices[i] += 1;
for (int j = i + 1; j < r; j++)
indices[j] = indices[j - 1] + 1;
for (i = 0; i < r; i++)
temp[i] = arr[indices[i]];
System.out.println(Arrays.toString(temp));
}
}
}
}

How to populate an array till its length with some specific values from another array?

I have a function
int[ ] fill(int[ ] arr, int k, int n) that returns an array with the length n and values consists of repetition of first k elements.
My code is:
class Repeat_block {
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 3;
int n = 10;
int arr[] = { 1, 2, 3, 5, 9, 12, -2, -1 };
System.out.println(Arrays.toString(fill(arr, k, n)));
}
public static int[] fill(int[] arr, int k, int n) {
int arr2[] = new int[n];
if (k == 0 || n <= 0) {
return null;
}
for (int i = 0; i < n; i++) {
if (i <k) {
arr2[i] = arr[i];
}
}
return arr2;
}
}
The function should return 1,2,3,1,2,3,1,2,3,1
but it's returning 1, 2, 3, 0, 0, 0, 0, 0, 0, 0 . I tried with so many ideas
but could not figure out to get the right logic. Anybody with some best ideas.
Once i == k, you need to reset it to 0. Hence you need to use two loop variables.
for (int i = 0, j = 0; i < n; i++, j++) {
if (j == k) {
j = 0;
}
arr2[i] = arr[j];
}
Replace your for-loop with:
for (int i = 0; i < n; i++) {
arr2[i] = arr[i % k]
}
Try this.
public static int[] fill(int[] arr, int k, int n) {
if (k == 0 || n <= 0) {
return null;
}
int[] ret = new int[n];
int counter = 0;
int value = 1;
while (counter < n) {
if (value > k) value = 1;
ret[counter] = value;
value++;
counter++;
}
return ret;
}
I thought it will be easy using streams and I am sure that it can be done much easier but here is my poor attempt:
import java.util.*;
import java.lang.*;
import java.util.stream.Collectors;
class Main
{
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 3;
int n = 10;
int arr[] = { 1, 2, 3, 5, 9, 12, -2, -1 };
fill(arr, k, n);
}
public static void fill(int[] arr, int k, int n) {
String elementsToCopy = Arrays.stream(arr)
.limit(k)
.mapToObj(String::valueOf)
.reduce((a,b) -> a.concat(",").concat(b))
.get();
List<String> resultInList = Collections.nCopies(n, elementsToCopy);
resultInList
.stream()
.collect(Collectors.toList());
System.out.println(resultInList
.toString()
.replace(" ", "")
.replace("[", "")
.substring(0, n+n-1));
}
}
Just for practice, I done that in Python3 :
def fill(arr,k,n):
c = math.ceil(n/k)
return (arr[0:k]*c)[0:n]

Waffle Stacking Algorithm needs improvement

I am working on a problem called Waffle Stacking. I am aware that a question already exists but the post needed to know where to start but I already have most of it done. The problem can be seen here: http://www.hpcodewars.org/past/cw16/problems/Prob20--WaffleStacking.pdf
My algorithm calculates the 120 permutations (5!) of the String "12345". I then place then row by row and make sure that they match the side clues. Then I check if it so far matches the top side. (Meaning that I go through the tiles that I currently have and I find the tallest stack and I look for the unused stacks and check if they are higher than the current highest stack and then I can see if I use the unused stacks they will match the clue). Using the example, my algorithm is very flawed. It produces only 4 rows and only one is correct. I believe it is due to checking the column. Any help is apprectated with checking the top and bottom sides.
package HP2013;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class WaffleStacking
{
public static String t[];
public static String l[];
public static String r[];
public static String b[];
public static void getInput()
{
try{
Scanner keyb = new Scanner(new File("src/HP2013/WaffleStacking.dat"));
t = keyb.nextLine().split(" ");
l = new String[5];
r = new String[5];
for (int i = 0; i < 5; i++)
{
String a[] = keyb.nextLine().split(" ");
l[i] = a[0];
r[i] = a[1];
}
b = keyb.nextLine().split(" ");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static ArrayList<String> perms = new ArrayList<String>();
public static void getPerms(String s)
{
getPerms("", s);
}
public static void getPerms(String pfx, String s)
{
int n = s.length();
if (n == 0)
perms.add(pfx);
else
{
for (int i = 0; i < s.length(); i++)
getPerms(pfx + s.charAt(i) + "", s.substring(0, i) + s.substring(i + 1));
}
}
public static void solve()
{
int mat[][] = new int[5][5];
for (int r = 0; r < 5; r++)
{
String row = "";
for (int p = 0; p < perms.size(); p++)
{
if (goodRow(perms.get(p), r))
{
row = perms.get(p);
for (int c = 0; c < row.length(); c++)
mat[r][c] = Integer.valueOf(row.charAt(c) + "");
if (uniqueCol(mat, r + 1) && goodCol(mat, r + 1))
break;
else
{
mat[r] = new int[] {0, 0, 0, 0, 0}.clone();
}
}
}
}
for (int m[] : mat)
System.out.println(Arrays.toString(m));
}
public static boolean uniqueCol(int mat[][], int rStop)
{
for (int c = 0; c < mat.length; c++)
{
ArrayList<Integer> col = new ArrayList<Integer>();
for (int r = 0; r < rStop; r++)
col.add(mat[r][c]);
Collections.sort(col);
for (int i = 0; i < col.size() - 1; i++)
if (col.get(i) == col.get(i + 1))
return false;
}
return true;
}
public static boolean goodRow(String row, int index)
{
int left = 0;
int max = -1;
for (int i = 0; i < row.length(); i++)
{
int stack = Integer.valueOf(row.charAt(i) + "");
if (stack > max)
{
left++;
max = stack;
}
}
int right = 0;
max = -1;
for (int i = row.length() - 1; i >= 0; i--)
{
int stack = Integer.valueOf(row.charAt(i) + "");
if (stack > max)
{
right++;
max = stack;
}
}
if (left == Integer.valueOf(l[index]) && right == Integer.valueOf(r[index]))
return true;
return false;
}
public static boolean goodCol(int mat[][], int rStop)
{
return checkTop(mat, rStop);
}
public static boolean checkTop(int mat[][], int rStop)
{
for (int c = 0; c < 5; c++)
{
int left = Integer.valueOf(t[c] + "");
int max = -1;
String used = "";
for (int r = 0; r < rStop; r++)
{
int stack = mat[r][c];
used += stack;
if (stack > max)
{
max = stack;
left--;
}
}
ArrayList<Integer> leftovers = new ArrayList<Integer>();
for (int n = 1; n <= 5; n++)
{
if (!used.contains(n + ""))
leftovers.add(n);
}
for (int j = 0; j < leftovers.size(); j++)
{
if (leftovers.get(j) > max)
{
max = leftovers.get(j);
left--;
}
}
if (left > 0)
return false;
}
return true;
}
public static void main(String args[])
{
getInput();
getPerms("12345");
solve();
}
}
Input:
2 2 3 2 1
4 1
1 4
3 2
2 2
3 2
3 2 1 3 4
Output:
[1, 3, 2, 4, 5]
[5, 1, 4, 3, 2]
[2, 4, 1, 5, 3]
[3, 2, 5, 1, 4]
[0, 0, 0, 0, 0]
So the first problem I see is no way to jump out when you've found a good answer. You're loops are probably continuing on after they've found the correct answer and unrolling to a point where you're losing the last row because of your else clause for a bad match.
Bottom side checking was not the problem, I overthought it; It should be very similar to top side checking. The solve method was very faulty and I switched to a recursive solution which ended up solving the problem. That way I can try several possibilities of valid rows while maintaining unique columns and then check if the columns were valid as well. If they weren't I can continue trying different possibilities.

Filtering out ints on an array

method takes in an array of ints and returns the new array of ints without even ints. Ive written something up but cannot get the print right in the main method....heres what I have
//filterAway method taking out evens from string
public static int[] filterArray(int[] x){
int [] arrayOne;
int size = 0;
for(int i=0; i<x.length; i++){
if(x[i] % 2 != 0){
size++;
}
}
arrayOne = new int [size];
int index =0;
for(int i=0; i<x.length; i++){
if(x[i] % 2 != 0){
arrayOne[index] = x[1];
index++;
}
}
return arrayOne;
}
//main
public static void main(String args[]){
int[] f = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i =0; i <f.length; i++){
System.out.print(f[i] + " ");
}
System.out.println(" ");
//here is where im struggling.
int [] fA= (filterAway); // say the string is 1-12....cannot get
// filtered array to print
for (int i =0; i <fA.length; i++){
System.out.print(arrayOne[i] + " ");
}``
System.out.println(" ");
}
Fixing the Display Problem
Try this revised main method, just replace YourClassName with your class name:
public static void main(String args[]) {
int[] f = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
for (int i = 0; i < f.length; i++) {
System.out.print(f[i] + " ");
}
System.out.println(" ");
// here is where im struggling.
int[] fA = YourClassName.filterArray(f);
// filtered array to print
for (int i = 0; i < fA.length; i++) {
System.out.print(fA[i] + " ");
}
System.out.println(" ");
}
However, you'll see you might end up getting something like 2, 2, 2, 2 there. You need to revisit your filterArray function.
Fixing the filterArray function
Since the title of your question is Filtering Out Ints in Java, here's the culprit, change 1 to i, that's why it gives out 2, 2, 2, 2. Also, you want even numbers, so you should look for 0 modulo, change your comparator to ==, instead of !=.
Here's what you should do with your requirements:
package com.sandbox;
public class Sandbox {
public static void main(String[] args) {
int[] all = new int[]{1, 2, 3, 4, 5, 6};
int[] filtered = odds(all);
for (int i : filtered) {
System.out.println(i);
}
}
private static int[] odds(int[] all) {
int sizeOfResult = 0;
for (int i : all) {
if (isOdd(i)) {
sizeOfResult++;
}
}
int[] result = new int[sizeOfResult];
int resultIndex = 0;
for (int i : all) {
if (isOdd(i)) {
result[resultIndex] = i;
resultIndex++;
}
}
return result;
}
private static boolean isOdd(int i) {
return i % 2 != 0;
}
}
Here's what I'd do if I were writing this on my own though: I'd use a List instead of an array, and I'd use CollectionUtils.filter. Here's a snippet of code that will do what you want:
package com.sandbox;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.primitives.Ints.asList;
public class Sandbox {
public static void main(String[] args) {
List<Integer> result = new ArrayList<Integer>(asList(1, 2, 3, 4, 5, 6));
CollectionUtils.filter(result, new Predicate() {
#Override
public boolean evaluate(Object o) {
return isOdd((Integer) o);
}
});
for (Integer integer : result) {
System.out.println(integer);
}
}
private static boolean isOdd(int i) {
return i % 2 != 0;
}
}
You will need to pass your f[] as an argument to your filterAway() method.
public static void main(String args[]){
int[] f = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i =0; i <f.length; i++){
System.out.print(f[i] + " ");
}
System.out.println(" ");
int [] fA= filterArray(f);
for (int i =0; i <fA.length; i++){
System.out.print(fA[i] + " ");
}
System.out.println();
}

Categories

Resources