removing duplicates from sorted array doesn't work - java

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.
I came up with below solution but this doesn't return correct output - I mean my input array still has duplicate values in it? Is there anything wrong I did?
public class Solution {
public static void main(String[] args) {
int[] input = new int[] { 1, 1, 3, 7, 7, 8, 9, 9, 9, 10 };
int length = input.length;
if (length == 0 || length == 1) {
System.out.println(length);
System.exit(0);
}
int i = 1;
for (int j = 1; j < length; j++) {
if (input[j] != input[j - 1]) {
input[i] = input[j];
i++;
}
}
if (i < length) {
input[i] = '\0';
}
System.out.println(i);
System.out.println(Arrays.toString(input));
}
}
NOTE: This is not homework, just preparing for an interview.

Java is not C. You don't mark the end of an array with a null pointer or zero character. Java arrays have a constant length and it never changes.
Your algorithm actually works well, but you probably want to put zero in all the array elements beyond i, to make it clear that those elements are unused. Use an actual 0, not '\0' which is a char value, which only happens to be assignment-compatible with int, but is not actually proper here.
Note also that the assignment expects you to return the length. This probably means that you have to write this as a method, which accepts the array as a parameter and returns the new length.

An array's length in Java cannot be altered after initialization, so you're forced to make a copy with the new size. Actually, the length parameter of a Java array is declared as final, so it cannot be changed once it's set.

Related

How to fill in only the even indexes of an ArrayList?

So I was trying to produce an arraylist where the even indexes were all filled. Something like this [1, -, 1, -, 1, -........]. But it's giving me an index out of bounds error. Why is that?
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<Integer> a = new ArrayList<>(10);
for (int i=0; i<11; i+=2) {
a.add(i, new Integer(1234));
}
}
}
Remember indices always start with 0.
You've created an arraylist with size 10, which means you should iterate through index 9, not 10.
Your for loop should be:
for (int i = 0; i < 10; i += 2)
Arrays use zero based indexing meaning you can reference a[0] through a[9]. so your constraint in the for loop
Should be i < 10. I’ll edit this answer and give more detail when I get home.
First, you loop constraint is off, for an array (and ArrayList) of size 10, indices are 0 through 9, means you need to check for i < 10.
Second, the parameter of ArrayList constructor (10 in this case) is the capacity, but not size - it's still empty, no actual elements in there. So you need to add zeroes (or nulls) in the loop too:
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
a.add(1234);
} else {
a.add(0); // or a.add(null)
}
}

How would I allow this to go through every element to check if it is equal?

So I was trying to build a solitaire encryption program, but I keep running into a problem when it comes to this method. The char array a represents the word the user inputs (converted it into an array to make it easier) and the char array b represents the alphabets so it has 25 indexes. What I am trying to do is match the alphabet to its number. It seemed simple enough but I am having a hard time as it keeps throwing an ArrayIndexOutOfBoundsException. I have tried to use for loops, nested for loops and other tests but it keeps throwing the exception or just outputs unexpected results such as [0, 0, 0, 0, 0]. I have debugged it and it seems like b[i] never equals a[j] so j will always be 0.
public static int[] converter(char[] a, char[] b){
int[] res = new int[a.length];
int i = 0;
int j = 0;
while(i < a.length){
if(b[i] == Character.toUpperCase(a[j])){ //Does not run through the first loop at all
res[j] = i + 1;
j = j + 1;
} else {
i = i + 1;
}
}
return res;
}
Please do not link the similar question. It does not answer my question.
The code below is a solution. We want the wordCharacterIndex to iterate through the word to see the place where a character is. The characterIndex iterates through the characters to compare with the word's character present at the wordCharacterIndex. After setting the result, we need to reset the characterIndex so that it goes back to the first character in the character array to compare with the other word characters, if we didn't, the following characters of the word would need to be at a higher character index, which is not what we want. Naming variables actual words is very important to better understand what you are trying to do within your code. You were comparing i < a.length while you were iterating through b[i] which made it possible to go larger than b's bounds and therefore cause an ArrayIndexOutOfBoundsException. I hope this helps you better understand.
public static int[] converter(char[] word, char[] characters){
int[] result = new int[word.length];
int characterIndex = 0;
int wordCharacterIndex = 0;
while(wordCharacterIndex < word.length){
if(characters[characterIndex] == Character.toUpperCase(word[wordCharacterIndex])){
result[wordCharacterIndex] = characterIndex + 1;
wordCharacterIndex++;
characterIndex = 0;
} else {
characterIndex++;
}
}
return result;
}

sort an array, so that first and last element will form a "pair"

I have an array of objects which I want to sort by indices in the following order. I will always have an array size to the power of 2.
Example array size: 8. Indices: [0][1] [2][3] [4][5] [6][7]
After sort: [0][7] [1][6] [2][5] [3][4]
So basically alternating between first and last element which was not sorted yet.
I already thought of a way of doing it, and I can get the "pairs" but they are in the wrong order (and I think it would not work with any other to the power of 2 array?).
Here I'm using an int array and their indices as values to make it simpler for myself.
int[] array = new int[]{0,1,2,3,4,5,6,7};
int[] sortedArray = new int[8];
for(int i = 0; i < array.length; i+=2){
sortedArray[i] = array[i];
}
for(int i = 1; i < array.length; i+=2){
sortedArray[i] = array[array.length - i];
}
Output: [0][7] [2][5] [4][3] [6][1]
You can do this with a single loop. Consider the following algorithm:
int[] array = new int[]{0,1,2,3,4,5,6,7};
int[] sortedArray = new int[8];
for(int i = 0; i < array.length; i+=2){
sortedArray[i] = array[i/2];
sortedArray[i + 1] = array[array.length - i/2 - 1];
}
System.out.println(Arrays.toString(sortedArray)); // prints [0, 7, 1, 6, 2, 5, 3, 4]
This creates the final array by setting two values at a time:
every even index of the result array is mapped with the first values of the initial array
every odd index of the result array is mapped with the last values of the initial array
Here's a recursive approach to it, and improvements exist.
Motivation: Work your way through the array until you're left with only two values to compare. Once you're done, simply print them. Otherwise, print the value and continue slicing the array. We use two index locations to help us walk through the array, as each one governs its end of the array. We cease recursion when the difference between our start and end index is 1.
Steps to guard against silly things, like a zero-length array, I leave as an exercise for the reader.
public static void arrangeArray(int[] array) {
arrangeArray(array, 0, array.length - 1);
}
private static void arrangeArray(int[] array, int startIndex, int endIndex) {
System.out.printf("[%d][%d]\t", array[startIndex], array[endIndex]);
if(endIndex - startIndex > 1) {
arrangeArray(array, startIndex + 1, endIndex - 1);
}
}
You can extend a List and then Override the way this List works with indices so 0 remains 0 but 1 becomes physically a 2 in your internal array.
If you implement this object correctly, Collections.sort() won't see the difference. Then you can add your methods to get the internal Array for whatever you have to do.
The advantage of this approach is performance. You don't have to scramble the list yourself in a secondary step.
class swap
{
public static void main(String args[])
{
int arr[]={0,1,2,3,4,5,6,7};
int sorted[]=new int[8];
int end=7;
int i=1,j;
for(int k=0;k<8;k++)
{
sorted[k]=arr[k];
}
for(j=1;j<8;j=j+2)
{
sorted[j]=arr[end];
end--;
}
for(j=2;j<8;j=j+2)
{
sorted[j]=arr[i];
i++;
}
for(int k=0;k<8;k++)
System.out.println(sorted[k]);
}
}

Java: How to find index of last element of partially initialized sorted array

Suppose I create an int array of size N. Then I fill up the array with sorted numbers until index x, where 0 <= x < N-1. How can I find the index x?
Here's one of the examples of the array: {0,1,2,3,4,0,0,0,0,0}, and here's how I generated the array:
int[] arr = new int[10];
for (int i = 0; i < 5; i++) {
arr[i] = i;
}
Is there any Java syntax for this? I am specifically talking about Array not ArrayList.
====UPDATE====
Sorry for the confusion, the above array was just an example. Suppose the partially initialized array is given, such that we don't know how it was generated. Again, to be clear, the array can also be initialized as {0,0,0,1,2,6,7,0,0,0,0} where the last 0,0,0,0 part is the part from being uninitialized, whereas the first 0,0,0 is deliberately written by somebody else.
You should use Integer class and not int primitive data type. Read about more things you can do with Integer class
Integer arr[] = new Integer[10];
This is initialized to null for each element. Now you can add number to it.
public int indexOfArray(Integer [] arr) {
int i=0;
while(arr[i]!=null) {
i++;
}
return i;
}
You said your array is sorted. So, you can search for the biggest element into the array and then uses Arrays.asList(arr).indexOf(biggestElement);
int biggetsElement = arr[0];
for(int i=1; i < arr.length; i++){
if(arr[i] > biggestElement){
biggestElement = arr[i];
}
}
int index = Arrays.asList(arr).indexOf(biggestElement);
I'm not sure if it will work with int elements, if not you can use Integer elements instead.
Not possible as specified. What if the "sorted values" are all negative and end at -1, e.g.:
[-5,-4,-3,-2,-1, 0,0,0,0]
vs. "sorted values" that are all non-positive but end in 0 (spaces added to emphasize the end of the initial sorted numbers)
[-5,-4,-3,-2,-1,0, 0,0,0]
There's no way to tell afterwards which 0 is the "first" unsorted one.
Assuming you dont know what x is, and assuming that the only value of uninitialized elements is 0, and that all initialized elements cant have the value 0 (which is not true in your case), then you will just have to do a linear search for it -
int i=0;
while(arr[i]!=0) i++;
return i
Create for loop and put in it condition that will check if next element is sorted
Code:
int x
for(int i=0;i<arr.length;i++)
if(arr[i+1]-arr[i]!=1)
x=i;
You can use this :
int index = Arrays.binarySearch(theArray, 0);
Condition : the array must be sorted
edit
Use Integer :
Integer[] theArray = {0, 0, 0, 1, 2, 4, 7, null, null, null};
int index = Arrays.binarySearch(theArray, null);

Removing an element from an Array in java

So I am in the AP Computer Science class in High School so I'm not very experienced. I have a program to do that requires me to read in numbers from a file, put those numbers into an array and then remove all of the 0's from the array.
So if the numbers are: 0,2,4,6,0,5,3,5...
I would need to create an array: [0,2,4,6,0,5,3,5]
and then remove the 0's: [2,4,6,5,3,5]
I have to do this using arrays and I am not allowed to create a second array to do this. I have looked all over online and the Java API's to find a method that can remove an element from an array but I simply can't find one. If somebody has any idea of one that I can use or a direction to steer me in, your advice would be much appreciated.
THIS IS THE QUESTION WORD FOR WORD:
1. Write a program that reads a text file(compact.txt) and stores the integers in an array. Your instructor will provide this text file.
2. Write a method compact that removes all zeroes from the array, leaving the order of the elements unchanged. All local variables within this function must be scalar. In other words, you may not use a second array to solve the problem.
3. Do not solve the problem simply by printing out only the non-zero values in the array. The compact method must remove all zeroes from the array.
You could try the following: Since you cannot modify the length of the array, you can arrange it so you put all zeroes at the end of the array and with value -1 (this is optional, just to indicate they are zeroes).
public static void main(String[] args)
{
int[] arr = { 0, 1, 2, 0, 3, 0, 4, 0, 5, 6, 7 };
int[] arrWithoutZeros = compact(arr);
for (int i : arrWithoutZeros) {
System.out.println(i);
}
}
private static int[] compact(int[] arr)
{
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
int j = 0;
for (j = i; j < arr.length - 1; j++) {
arr[j] = arr[j + 1];
}
arr[j] = -1;
i--;
}
}
return arr;
}
Output:
1
2
3
4
5
6
7
-1
-1
-1
-1
Note: This meets the question requirements:
Leaves the order of elements unchanged (it changes its position, but not the order)
Don't use a second array
Not solved by just printing the non-zero elements
Removes zeros from array (they are now -1)
I'm not normally a fan of doing homework, but I found this one interesting and impossible as written, so here goes.
This is much like Christian's answer, but I'm using Integer instead of int so that I can set the 0s to null instead of some other integer. I've also avoided the extra loop he has to copy every remaining value down on every single 0, instead iterating the array once and then iterating the tail only once to set the null values.
public class ArrayCompact {
private static Integer[] ARRAY = { 1, 3, 5, 0, 7, 9, 0, 2, 0, 4, 6, 0, 8, -1, 0 };
public static void main( String[] args ) {
printArray( compact(ARRAY ));
}
public static Integer[] compact( Integer[] ints ) {
int j = 0;
for ( int i = 0; i < ints.length; i++ ) {
if ( ints[i] != 0 ) {
ints[j++] = ints[i];
}
}
for ( int i = j; i < ints.length; i++ ) {
ints[i] = null;
}
return ints;
}
public static void printArray( Integer[] ints ) {
for ( Integer i : ints ) {
System.out.print( i + " " );
}
}
}
Output 1 3 5 7 9 2 4 6 8 -1 null null null null null Technically I guess you could just not print the nulls, since that's not not printing 0s...
Another Edit:
(I think previous answer is still meaningful and I am keeping it at the end. This edit is mainly for suggestion specific to the homework requirement)
Base on the question, the compact logic treat 0 as something that is "meaningless" and need to be "removed". Therefore we don't really need some kind of special value after we "shrink" the array. Simply keeping it as 0 will help.
Apart from the "copy [i+1,end] to i" method, there is another (easier and possibly faster) method that you can do to "remove" the zeros.
Basically what you need is, iterate through the array. If you encounter a 0, then find the first non-zero value after that position, and swap the zero with that non-zero value.
Which looks like this in psuedo code:
for (i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
for (j = i+1; j < arr.length; j++) {
if (arr[j] != 0) {
arr[i] = arr[j];
arr[j] = 0;
break;
}
}
}
}
// arr is "shrinked" here
Then it is your choice to return an actually shrinked copy of array, or simply return the "so-called-shrinked" array with 0s at the end.
Something for you to think of:
First, in Java, size of array is fixed, therefore, it is not possible to shrink array's size. Therefore, it is IMPOSSIBLE to have a result array with less elements without creating a new array
If it is fine for you to leave unused element at the end as some special values (e.g. -ve, or 0 etc), the removing element at position i from array essentially means:
copy array elements [i+1 to end] to position i, and replace arr[end] with special empty value
e.g. [1, 3, 5, 7, 9]
If I want to remove index 2, what I need to do is to copy element 3-4 to position 2:
[1,3,5,7,9] -> [1,3,7,9,9]
^^^ ^^^
and replace end element with some special value (e.g. -1 in this example):
[1,3,7,9,9] -> [1,3,5,7,-1]
Array copy can be done easily by using System.arrayCopy()
Have just seen update in your question.
Most of my answer is still valid, and here is some extra update with regards to your question:
If you are sure that no Integer.MIN will appear in your input, then use my above mentioned approach, and update the input array accordingly.
You may consider using Integer[] instead of int[], so that you can put null
This is the most "normal" approach, but given your requirement, this may or may not be valid. The question ask you to have only scalar LOCAL VARIABLES. Which implies to me that, if I don't create another variable, I can still return another array (seems that the question is only trying to stop you using another array in process of compacting). Just follow what I have mentioned above, however, instead of replacing the end position with some special value, just keep a local var which is array length. Whenever you remove an element (by copying [i+1, 0] to position i), decrement the array length var. At the end, return a new copy of "shrinked" array by using Arrays.copyOf(oldArray, newLength).
Here is a piece of psuedo-code for point 3:
int[] compact(int[] input) {
int arrSize = input.length;
int i = 0;
while (i < arrSize) {
if (input[i] == 0) {
copy input[i+1 to end] to input[i to end-1]
arrSize--;
} else {
i++;
}
}
return Arrays.copyOf(input, arrSize);
}

Categories