Related
I am working on a method that will take an integer array and fold it in half x number of times. This method would take an integer array like this {1,2,3,4,5} and output an the array {6,6,3} if it is folded once. Or it could take the input {5,6,7,8} and output {13,13} also folded once.
If the input is folded twice then {5,6,7,8} would turn into {26}.
import java.util.Arrays;
public class Kata
{
public static int[] foldArray(int[] array, int runs)
{
int[] tempArray = array;
for(int j=0; j<runs; j++){
for(int i=0; i<tempArray.length; i++){
tempArray[i] += tempArray[tempArray.length - i];
}
}
int[] outputArray = Arrays.copyOfRange(tempArray, (tempArray.length/2));
return outputArray;
}
}
The problem with your implementation is the way in which you use tempArray:
int[] tempArray = array;
This "aliases" tempArray to the original array, so any modifications to tempArray also happen to the original array. This means that tempArray's length is not going to change from run to run, so any fold after the first one would be invalid.
You need to make tempArray a copy of the initial ⌈n/2⌉ elements on each iteration of the outer loop. To round half-length up, use this expression:
int halfLength = (tempArray.length+1)/2;
int[] tempArray = Arrays.copyOfRange(tempArray, halfLength);
This will deal with arrays of odd length.
At the end of each outer loop iteration replace array with tempArray.
You can also solve your problem recursively:
public static int[] foldArray(int[] array, int runs) {
if (runs == 0) {
return array;
}
int[] tmp;
if (array.length % 2 == 0) {
tmp = new int[array.length / 2];
for (int i = 0; i < array.length / 2; i++) {
tmp[i] = array[i];
}
} else {
tmp = new int[array.length / 2 + 1];
for (int i = 0; i < array.length / 2 + 1; i++) {
tmp[i] = array[i];
}
}
for (int i = 0; i < array.length / 2; i++) {
tmp[i] += array[array.length - i - 1];
}
return foldArray(tmp, runs - 1);
}
public static void main(String[] args) {
System.out.println(Arrays.toString(foldArray(new int[]{1, 2, 3, 4, 5}, 1)));
System.out.println(Arrays.toString(foldArray(new int[]{5, 6, 7, 8}, 1)));
System.out.println(Arrays.toString(foldArray(new int[]{5, 6, 7, 8}, 2)));
}
Note that you need to be careful with the length of the input arrays - whether it's odd or even.
Solution in JavaScript:
function fold(arr, num) {
if (num === 0 || arr.length === 1) {
return arr;
}
let result = [];
while (arr.length > 1) {
result.push(arr.shift() + arr.pop());
}
if(arr.length === 1){
result.push(arr[0]);
}
return fold(result, num - 1);
}
Example:
const arr = [1, 2, 3, 4, 5];
fold(arr, 2); --> [9,6]
I'm trying to write a method that takes a sorted array and an integer, creates a new array that is 1 size larger, and inserts the new integer and keeps it sorted.
I've tried a few different implementations and had them to work - but for this specific one, I can't grasp where it's going wrong.
int[] array1 = new int[]{1, 2, 3, 4, 6, 7, 8};
int[] printArray = insert(array1, 5);
are the arrays, and the method is
public static int[] insert(int[] a, int k) {
int[] s = new int[a.length + 1];
for(int i = 0; i < a.length; i++) {
if(k < s[i]) {
s[i] = k;
for(int j = i + 1; j < s.length; j++) {
s[j] = a[i];
i++;
}
return s;
} else {
s[i] = a[i];
}
}
return s;
}
This method prints out 1, 2, 3, 4, 6, 7, 8, 0, instead of 1, 2, 3, 4, 5, 6, 7, 8.
Change
if(k < s[i]) {
to
if(k < a[i]) {
in line 4.
Actually in the following line you are creating an array with all elements zero:
int[] s = new int[a.length + 1];
s[0] to s[7] will be 0.
Your loop counter i runs from 0 to a.length but the point to note is all the elements of array s will be zero. You are comparing k with s[i] which is zero and for that reason the shifting of arrays never happen (if block never executes).
You need to do two things to fix it.
Initialize element zero of s with the value of a[0].
Compare element with previous element to figure out position to insert.
The final code is:
public static int[] insert(int[] a, int k) {
int[] s = new int[a.length + 1];
s[0] = a[0];
for(int i = 1; i < a.length; i++) {
if(k < s[i-1]) {
s[i] = k;
for(int j = i + 1; j < s.length; j++) {
s[j] = a[i];
i++;
}
return s;
} else {
s[i] = a[i];
}
}
return s;
}
Now you will get:
[1, 2, 3, 4, 6, 5, 7, 8]
I would start by using Arrays.copyOf(int[], int) to create a new array that is one larger than the input. Then iterate that array until I reached the index that the new value belongs at. Then use System.arraycopy(Object,int,Object,int,int) to copy the values into the end of the array. That might look something like
public static int[] insert(int[] a, int k) {
int[] s = Arrays.copyOf(a, a.length + 1);
for (int i = 0; i < s.length; i++) {
if (a[i] < k) {
continue;
}
System.arraycopy(a, i, s, i + 1, s.length - i - 1);
s[i] = k;
break;
}
return s;
}
Which I tested with Arrays.toString(int[]) like
public static void main(String s[]) throws IOException {
int[] array1 = new int[] { 1, 2, 3, 4, 6, 7, 8 };
int[] printArray = insert(array1, 5);
System.out.println(Arrays.toString(printArray));
}
And I get the (expected)
[1, 2, 3, 4, 5, 6, 7, 8]
I have searched a lot in google but I didnt get any kind of solution I could use. Suppose input of array is:
{3,1,2,4,9,8,7,6,5,10}
then output must be like this:
{1,2,3,4,5,10,9,8,7,6}
by using Basic Java .
Your array: {3,1,2,4,9,8,7,6,5,10}
Sort it in ascending order: {1,2,3,4,5,6,7,8,9,10}
Break this array into two half arrays: {1,2,3,4,5}{6,7,8,9,10}
Sort the second array in descending order or reverse it: {10, 9,8,7,6}
Add the second array to the first array & you get: {1,2,3,4,5,10,9,8,7,6}
This would be the minimal code which uses an array of primitive ints:
static final int[] xs = {3,1,2,4,9,8,7,6,5,10};
static void sortAndReverse() {
Arrays.sort(xs);
for (int i = xs.length/2; i < dest(i); i++) {
int tmp = xs[i]; xs[i] = xs[dest(i)]; xs[dest(i)] = tmp;
}
System.out.println(Arrays.toString(xs));
}
static int dest(int i) { return 3*xs.length/2-i-1; }
If you're not ashamed of using wrapper objects, then this is unbeatable:
final Integer[] xs = {3,1,2,4,9,8,7,6,5,10};
final List<Integer> list = Arrays.asList(xs);
Collections.sort(list);
Collections.reverse(list.subList(list.size()/2, list.size()));
System.out.println(Arrays.toString(xs));
Please find the below code
import java.util.Arrays;
public class fre {
public static void main(String[] args) {
int[] vals = { 3, 1, 2, 4, 9, 8, 7, 6, 5, 10 };
Arrays.sort(vals); // Sorts the basic first array
int[] vals2 = Arrays.copyOfRange(vals, vals.length / 2, vals.length); // Gets the las values of the arrays i.e. it devies the array in multiple same part and another array is created
// Below loop will reverse the second array
for (int i = 0; i < vals2.length / 2; i++) {
int temp = vals2[i];
vals2[i] = vals2[vals2.length - 1 - i];
vals2[vals2.length - 1 - i] = temp;
}
vals = Arrays.copyOfRange(vals, 0, vals.length / 2);
// Final array array1and2 will be created where we will append first array with second array
int[] array1and2 = new int[vals.length + vals2.length];
System.arraycopy(vals, 0, array1and2, 0, vals.length);
System.arraycopy(vals2, 0, array1and2, vals.length, vals2.length);
// Prints the final result array
System.out.println(Arrays.toString(array1and2));
}
}
Output
[1, 2, 3, 4, 5, 10, 9, 8, 7, 6]
You can use the java features to do this too ... Use
public static <T> void sort(T[] a,
int fromIndex,
int toIndex,
Comparator<? super T> c)
But the elements need to be objects ... The comparator needs to be changed while sorting the first half and second half of the array.
Should be a bit simpler than manually reversing each item in the second half.
Integer [] array = { 3,1,2,4,9,8,7,6,5,10 };
Arrays.sort(array);
Arrays.sort(array, array.length/2, array.length, new Comparator<Integer>(){
#Override
public int compare(Integer o1, Integer o2)
{
return -o1.compareTo(o2);
}
});
System.out.println(Arrays.toString(array));
[1, 2, 3, 4, 5, 10, 9, 8, 7, 6]
IPSOS isn't it?
int m;
if(array.length%2==0)
m=array.length/2;
else
m=(array.length+1)/2;
for(int i=0; i<array.length; ++i){
if(i<m){
int min = i;
for(int j=i+1; j<m;++j){
if(array[min]>array[j]){
min=j;
}
int tem = array[i];
array[i]=array[min];
array[min]=tem;
}
}
else {
int max = i;
for(int k=i+1; k<array.length; ++k){
if(array[max]<array[k]){
max=k;
}
int te = array[i];
array[i]=array[max];
array[max]=te;
}
}
}
for(int i=0;i<array.length;++i){
System.out.print(array[i] + " ");
}
1. Sort the array input_Array[]
2. j = lenght(input_Array)-1
3. loop i = lenght(input_Array)/2 to j
swap(input_Array[i] , input_Array[j-i])
input: 3,1,2,4,9,8,7,6,5,10
output: 1 3 5 7 9 10 8 6 4 2 (uniform acceding and descending )
public class AscendingDecending {
public static void main(String[]args) {
int a[]= {2,3,2,5,7,5,6,3};
int i,j,temp;
//Traverse the element of array
System.out.println("Input:");
for(i=0; i<a.length; i++) {
System.out.print(" "+ a[i]);
}
//lets move for ascending function
System.out.println("");
System.out.println("Output:");
//Create a Swap Function for sorting
for(i=0; i<a.length; i++) {
for(j=i+1; j<a.length; j++) {
if(a[i]>a[j]) {
temp= a[i];
a[i]= a[j];
a[j]= temp;
}
}
}
// Now the input is in sorted order
for(i=0; i<a.length/2; i++) {
System.out.print(" "+ a[i]);
}
//For Descending
for(i=0; i<a.length; i++) {
for(int j=i+1; j<a.length; j++) {
if(a[i]<a[j]) {
temp= a[i];
a[i]= a[j];
a[j]= temp;
}
}
}
// Now the input is in sorted order
System.out.println(" ");
for(i=0; i<a.length/2; i++) {
System.out.print(" "+ a[i]);
}
}
}
I hope this piece of code will help:
static void printarray(int[] arr, int len)
{
Arrays.sort(arr);
for (int i = 0; i < len / 2; i++)
System.out.println(arr[i]);
for (int j = len - 1; j >= len / 2; j--)
System.out.println(arr[j]);
}
I need to move all 0's in an array to the end of the array.
Example: [1, 10, 0, 5, 7] should result in [1, 10, 5, 7, 0].
I am open to doing a reverse loop or a regular loop.
I cannot create a new array.
Here is what I have so far:
for (int i = arr.length; i <= 0; --i) {
if (arr[i] != 0) {
arr[i] = arr.length - 1;
}
}
Thanks!
SIZE(n) where n = arr.size, retain ordering:
Create an array that is the same size as the initial array you need to remove 0s from. Iterate over the original array and add each element to the new array provided it is not 0. When you encounter a 0, count it. Now, when you've reached the end of the first array, simply add the counted number of 0s to the end of the array. And, even simpler, since Java initializes arrays to 0, you can forget about adding the zeroes at the end.
Edit
Since you have added the additional constraint of not being able to create a new array, we need to take a slightly different approach than the one I've suggested above.
SIZE(1)
I assume the array needs to remain in the same order as it was before the 0s were moved to the end. If this is not the case there is another trivial solution as detailed in Brads answer: initialize a "last zero" index to the last element of the array and then iterate backwards swapping any zeros with the index of the last zero which is decremented each time you perform a swap or see a zero.
SIZE(1), retain ordering:
To move the 0s to the end without duplicating the array and keeping the elements in the proper order, you can do exactly as I've suggested without duplicating the array but keeping two indices over the same array.
Start with two indices over the array. Instead of copying the element to the new array if it is not zero, leave it where it is and increment both indices. When you reach a zero, increment only one index. Now, if the two indices are not the same, and you are not looking at a 0, swap current element the location of the index that has fallen behind (due to encountered 0s). In both cases, increment the other index provided the current element is not 0.
It will look something like this:
int max = arr.length;
for (int i = 0, int j = 0; j < max; j++) {
if (arr[j] != 0) {
if (i < j) {
swap(arr, i, j);
}
i++
}
}
Running this on:
{ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 }
yeilds:
{ 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 }
I made a fully working version for anyone who's curious.
Two choices come to mind
Create a new array of the same size, then Iterate over your current array and only populate the new array with values. Then fill the remaining entries in the new array with "zeros"
Without creating a new array you can iterate over your current array backwards and when you encounter a "zero" swap it with the last element of your array. You'll need to keep a count of the number of "zero" elements swapped so that when you swap for a second time, you swap with the last-1 element, and so forth.
[Edit] 7 years after originally posting to address the "ordering" issue and "last element is zero" issues left in the comments
public class MyClass {
public static void main(String[] args) {
int[] elements = new int[] {1,0,2,0,3,0};
int lastIndex = elements.length-1;
// loop backwards looking for zeroes
for(int i = lastIndex; i >=0; i--) {
if(elements[i] == 0) {
// found a zero, so loop forwards from here
for(int j = i; j < lastIndex; j++) {
if(elements[j+1] == 0 || j == lastIndex) {
// either at the end of the array, or we've run into another zero near the end
break;
}
else {
// bubble up the zero we found one element at a time to push it to the end
int temp = elements[j+1];
elements[j+1] = elements[j];
elements[j] = temp;
}
}
}
}
System.out.println(Arrays.toString(elements));
}
}
Gives you...
[1, 2, 3, 0, 0, 0]
Basic solution is to establish an inductive hypothesis that the subarray can be kept solved. Then extend the subarray by one element and maintain the hypothesis. In that case there are two branches - if next element is zero, do nothing. If next element is non-zero, swap it with the first zero in the row.
Anyway, the solution (in C# though) after this idea is optimized looks like this:
void MoveZeros(int[] a)
{
int i = 0;
for (int j = 0; j < a.Length; j++)
if (a[j] != 0)
a[i++] = a[j];
while (i < a.Length)
a[i++] = 0;
}
There is a bit of thinking that leads to this solution, starting from the inductive solution which can be formally proven correct. If you're interested, the whole analysis is here: Moving Zero Values to the End of the Array
var size = 10;
var elemnts = [0, 0, 1, 4, 5, 0,-1];
var pos = 0;
for (var i = 0; i < elemnts.length; i++) {
if (elemnts[i] != 0) {
elemnts[pos] = elemnts[i];
pos++;
console.log(elemnts[i]);
}
}
for (var i = pos; i < elemnts.length; i++) {
elemnts[pos++] = 0;
console.log(elemnts[pos]);
}
int arrNew[] = new int[arr.length];
int index = 0;
for(int i=0;i<arr.length;i++){
if(arr[i]!=0){
arrNew[index]=arr[i];
index++;
}
}
Since the array of int's is initialized to zero(according to the language spec). this will have the effect you want, and will move everything else up sequentially.
Edit: Based on your edit that you cannot use a new array this answer doesnt cover your requirements. You would instead need to check for a zero(starting at the end of the array and working to the start) and swap with the last element of the array and then decrease the index of your last-nonzero element that you would then swap with next. Ex:
int lastZero = arr.length - 1;
if(arr[i] == 0){
//perform swap and decrement lastZero by 1 I will leave this part up to you
}
/// <summary>
/// From a given array send al zeros to the end (C# solution)
/// </summary>
/// <param name="numbersArray">The array of numbers</param>
/// <returns>Array with zeros at the end</returns>
public static int[] SendZerosToEnd(int[] numbersArray)
{
// Edge case if the array is null or is not long enough then we do
// something in this case we return the same array with no changes
// You can always decide to return an exception as well
if (numbersArray == null ||
numbersArray.Length < 2)
{
return numbersArray;
}
// We keep track of our second pointer and the last element index
int secondIndex = numbersArray.Length - 2,
lastIndex = secondIndex;
for (int i = secondIndex; i >= 0; i--)
{
secondIndex = i;
if (numbersArray[i] == 0)
{
// While our pointer reaches the end or the next element
// is a zero we swap elements
while (secondIndex != lastIndex ||
numbersArray[secondIndex + 1] != 0)
{
numbersArray[secondIndex] = numbersArray[secondIndex + 1];
numbersArray[secondIndex + 1] = 0;
++secondIndex;
}
// This solution is like having two pointers
// Also if we look at the solution you do not pass more than
// 2 times actual array will be resume as O(N) complexity
}
}
// We return the same array with no new one created
return numbersArray;
}
In case if question adds following condition.
Time complexity must be O(n) - You can iterate only once.
Extra
space complexity must be O(1) - You cannot create extra array.
Then following implementation will work fine.
Steps to be followed :
Iterate through array & maintain a count of non-zero elements.
Whenever we encounter a non-zero element put at count location in array & also increase the count.
Once array is iterated completely put the zeros at end of array till the count reach to original length of array.
public static void main(String args[]) {
int[] array = { 1, 0, 3, 0, 0, 4, 0, 6, 0, 9 };
// Maintaining count of non zero elements
int count = -1;
// Iterating through array and copying non zero elements in front of array.
for (int i = 0; i < array.length; i++) {
if (array[i] != 0)
array[++count] = array[i];
}
// Replacing end elements with zero
while (count < array.length - 1)
array[++count] = 0;
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
Time complexity = O(n), Space Complexity = O(1)
import java.util.Scanner;
public class ShiftZeroesToBack {
int[] array;
void shiftZeroes(int[] array) {
int previousK = 0;
int firstTime = 0;
for(int k = 0; k < array.length - 1; k++) {
if(array[k] == 0 && array[k + 1] != 0 && firstTime != 0) {
int temp = array[previousK];
array[previousK] = array[k + 1];
array[k + 1] = temp;
previousK = previousK + 1;
continue;
}
if(array[k] == 0 && array[k + 1] != 0) {
int temp = array[k];
array[k] = array[k + 1];
array[k + 1] = temp;
continue;
}
if(array[k] == 0 && array[k + 1] == 0) {
if(firstTime == 0) {
previousK = k;
firstTime = 1;
}
}
}
}
int[] input(Scanner scanner, int size) {
array = new int[size];
for(int i = 0; i < size; i++) {
array[i] = scanner.nextInt();
}
return array;
}
void print() {
System.out.println();
for(int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ShiftZeroesToBack sztb = new ShiftZeroesToBack();
System.out.print("Enter Size of Array\t");
int size = scanner.nextInt();
int[] input = sztb.input(scanner, size);
sztb.shiftZeroes(input);
sztb.print();
}
}
let's say we have an array
[5,4,0,0,6,7,0,8,9]
Let's assume we have array elements between 0-100, now our goal is to move all 0's at the end of the array.
now hold 0 from the array and check it with non zero element if any non zero element found swap with that element and so on, at the end of the loop we will find the solution.
here is the code
for (int i = 0; i < outputArr.length; i++)
{
for (int j = i+1; j < outputArr.length; j++)
{
if(outputArr[i]==0 && outputArr[j]!=0){
int temp = outputArr[i];
outputArr[i] = outputArr[j];
outputArr[j] = temp;
}
}
print outputArr[i]....
}
output:
[5,4,6,7,8,9,0,0,0]
Here is how i have implemented this.
Time complexity: O(n) and Space Complexity: O(1)
Below is the code snippet:
int arr[] = {0, 1, 0, 0, 2, 3, 0, 4, 0};
int i=0, k = 0;
int n = sizeof(arr)/sizeof(arr[0]);
for(i = 0; i<n; i++)
{
if(arr[i]==0)
continue;
arr[k++]=arr[i];
}
for(i=k;i<n;i++)
{
arr[i]=0;
}
output: {1, 2, 3, 4, 0, 0, 0, 0, 0}
Explanation: using another variable k to hold index location, non-zero elements are shifted to the front while maintaining the order. After traversing the array, non-zero elements are shifted to the front of array and another loop starting from k is used to override the remaining positions with zeros.
This is my code with 2 for loops:
int [] arr = {0, 4, 2, 0, 0, 1, 0, 1, 5, 0, 9,};
int temp;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
{
for (int j = i + 1; j < arr.length; j++)
{
if (arr[j] != 0)
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
break;
}
}
}
}
System.out.println(Arrays.toString(arr));
output: [4, 2, 1, 1, 5, 9, 0, 0, 0, 0, 0]
public static void main(String[] args) {
Integer a[] = {10,0,0,0,6,0,0,0,70,6,7,8,0,4,0};
int flag = 0;int count =0;
for(int i=0;i<a.length;i++) {
if(a[i]==0 ) {
flag=1;
count++;
}else if(a[i]!=0) {
flag=0;
}
if(flag==0 && count>0 && a[i]!=0) {
a[i-count] = a[i];
a[i]=0;
}
}
}
This is One method of Moving the zeroes to the end of the array.
public class SeparateZeroes1 {
public static void main(String[] args) {
int[] a = {0,1,0,3,0,0,345,12,0,13};
movezeroes(a);
}
static void movezeroes(int[] a) {
int lastNonZeroIndex = 0;
// If the current element is not 0, then we need to
// append it just in front of last non 0 element we found.
for (int i = 0; i < a.length; i++) {
if (a[i] != 0 ) {
a[lastNonZeroIndex++] = a[i];
}
}//for
// We just need to fill remaining array with 0's.
for (int i = lastNonZeroIndex; i < a.length; i++) {
a[i] = 0;
}
System.out.println( lastNonZeroIndex );
System.out.println(Arrays.toString(a));
}
}
This is very simple in Python. We will do it with list comprehension
a =[0,1,0,3,0,0,345,12,0,13]
def fix(a):
return ([x for x in a if x != 0] + [x for x in a if x ==0])
print(fix(a))
int[] nums = { 3, 1, 2, 5, 4, 6, 3, 2, 1, 6, 7, 9, 3, 8, 0, 4, 2, 4, 6, 4 };
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 3) {
list1.add(nums[i]);
} else if (nums[i] != 3) {
list2.add(nums[i]);
}
}
List<Integer> finalList = new ArrayList<>(list2);
finalList.addAll(list1);
}
}
int[] nums = {3,1,2,5,4,6,3,2,1,6,7,9,3,8,0,4,2,4,6,4};
int i = 0;
for(int j = 0, s = nums.length; j < s;) {
if(nums[j] == 3)
j++;
else {
int temp = nums[i];
nums[i] = nums[j];``
nums[j] = temp;
i ++;
j ++;
}
}
For Integer array it can be as simple as
Integer[] numbers = { 1, 10, 0, 5, 7 };
Arrays.sort(numbers, Comparator.comparing(n -> n == 0));
For int array :
int[] numbers = { 1, 10, 0, 5, 7 };
numbers = IntStream.of(numbers).boxed()
.sorted(Comparator.comparing(n -> n == 0))
.mapToInt(i->i).toArray();
Output of both:
[1, 10, 5, 7, 0]
Lets say, you have an array like
int a[] = {0,3,0,4,5,6,0};
Then you can sort it like,
for(int i=0;i<a.length;i++){
for(int j=i+1;j<a.length;j++){
if(a[i]==0 && a[j]!=0){
a[i]==a[j];
a[j]=0;
}
}
}
public void test1(){
int [] arr = {0,1,0,4,0,3,2};
System.out.println("Lenght of array is " + arr.length);
for(int i=0; i < arr.length; i++){
for(int j=0; j < arr.length - i - 1; j++){
if(arr[j] == 0){
int temp = arr[j];
arr[j] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
}
}
for(int x = 0; x < arr.length; x++){
System.out.println(arr[x]);
}
}
Have a look at this function code:
vector<int> Solution::solve(vector<int> &arr) {
int count = 0;
for (int i = 0; i < arr.size(); i++)
if (arr[i] != 0)
arr[count++] = arr[i];
while (count < arr.size())
arr[count++] = 0;
return arr;
}
import java.io.*;
import java.util.*;
class Solution {
public static int[] moveZerosToEnd(int[] arr) {
int j = 0;
for(int i = 0; i < arr.length; i++) {
if(arr[i] != 0) {
swap(arr, i, j);
j++;
}
}
return arr;
}
private static void swap(int arr[], int i, int j){
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
public static void main(String[] args) {
int arr[] =new int[] {1, 10, 0, 2, 8, 3, 0, 0, 6, 4, 0, 5, 7, 0 };
System.out.println(Arrays.toString(moveZerosToEnd(arr)));
}
}
Reimplemented this in Python:
Pythonic way:
lst = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]
for i, val in enumerate(lst):
if lst[i] == 0:
lst.pop(i)
lst.append(0)
print("{}".format(lst))
#dcow's implementation in python:
lst = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]
i = 0 # init the index value
for j in range(len(lst)): # using the length of list as the range
if lst[j] != 0:
if i < j:
lst[i], lst[j] = lst[j], lst[i] # swap the 2 elems.
i += 1
print("{}".format(lst))
a = [ 1, 2, 0, 0, 0, 3, 4, 0, 5, 0 ]
count = 0
for i in range(len(a)):
if a[i] != 0:
a[count], a[i] = a[i], a[count]
count += 1
print(a)
#op [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
I am trying to remove duplicates from a list by creating a temporary array that stores the indices of where the duplicates are, and then copies off the original array into another temporary array while comparing the indices to the indices I have stored in my first temporary array.
public void removeDuplicates()
{
double tempa [] = new double [items.length];
int counter = 0;
for ( int i = 0; i< numItems ; i++)
{
for(int j = i + 1; j < numItems; j++)
{
if(items[i] ==items[j])
{
tempa[counter] = j;
counter++;
}
}
}
double tempb [] = new double [ items.length];
int counter2 = 0;
int j =0;
for(int i = 0; i < numItems; i++)
{
if(i != tempa[j])
{
tempb[counter2] = items[i];
counter2++;
}
else
{
j++;
}
}
items = tempb;
numItems = counter2;
}
and while the logic seems right, my compiler is giving me an arrayindexoutofbounds error at
tempa[counter] = j;
I don't understand how counter could grow to above the value of items.length, where is the logic flaw?
You are making things quite difficult for yourself. Let Java do the heavy lifting for you. For example LinkedHashSet gives you uniqueness and retains insertion order. It will also be more efficient than comparing every value with every other value.
double [] input = {1,2,3,3,4,4};
Set<Double> tmp = new LinkedHashSet<Double>();
for (Double each : input) {
tmp.add(each);
}
double [] output = new double[tmp.size()];
int i = 0;
for (Double each : tmp) {
output[i++] = each;
}
System.out.println(Arrays.toString(output));
Done for int arrays, but easily coud be converted to double.
1) If you do not care about initial array elements order:
private static int[] withoutDuplicates(int[] a) {
Arrays.sort(a);
int hi = a.length - 1;
int[] result = new int[a.length];
int j = 0;
for (int i = 0; i < hi; i++) {
if (a[i] == a[i+1]) {
continue;
}
result[j] = a[i];
j++;
}
result[j++] = a[hi];
return Arrays.copyOf(result, j);
}
2) if you care about initial array elements order:
private static int[] withoutDuplicates2(int[] a) {
HashSet<Integer> keys = new HashSet<Integer>();
int[] result = new int[a.length];
int j = 0;
for (int i = 0 ; i < a.length; i++) {
if (keys.add(a[i])) {
result[j] = a[i];
j++;
}
}
return Arrays.copyOf(result, j);
}
3) If you do not care about initial array elements order:
private static Object[] withoutDuplicates3(int[] a) {
HashSet<Integer> keys = new HashSet<Integer>();
for (int value : a) {
keys.add(value);
}
return keys.toArray();
}
Imagine this was your input data:
Index: 0, 1, 2, 3, 4, 5, 6, 7, 8
Value: 1, 2, 3, 3, 3, 3, 3, 3, 3
Then according to your algorithm, tempa would need to be:
Index: 0, 1, 2, 3, 4, 5, 6, 7, 8, ....Exception!!!
Value: 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 5, 6, 7, 8, 6, 7, 8, 7, 8, 8
Why do you have this problem? Because the first set of nested for loops does nothing to prevent you from trying to insert duplicates of the duplicate array indices!
What is the best solution?
Use a Set!
Sets guarantee that there are no duplicate entries in them. If you create a new Set and then add all of your array items to it, the Set will prune the duplicates. Then it is just a matter of going back from the Set to an array.
Alternatively, here is a very C-way of doing the same thing:
//duplicates will be a truth table indicating which indices are duplicates.
//initially all values are set to false
boolean duplicates[] = new boolean[items.length];
for ( int i = 0; i< numItems ; i++) {
if (!duplicates[i]) { //if i is not a known duplicate
for(int j = i + 1; j < numItems; j++) {
if(items[i] ==items[j]) {
duplicates[j] = true; //mark j as a known duplicate
}
}
}
}
I leave it to you to figure out how to finish.
import java.util.HashSet;
import sun.security.util.Length;
public class arrayduplication {
public static void main(String[] args) {
int arr[]={1,5,1,2,5,2,10};
TreeSet< Integer>set=new TreeSet<Integer>();
for(int i=0;i<arr.length;i++){
set.add(Integer.valueOf(arr[i]));
}
System.out.println(set);
}
}
You have already used num_items to bound your loop. Use that variable to set your array size for tempa also.
double tempa [] = new double [num_items];
Instead of doing it in array, you can simply use java.util.Set.
Here an example:
public static void main(String[] args)
{
Double[] values = new Double[]{ 1.0, 2.0, 2.0, 2.0, 3.0, 10.0, 10.0 };
Set<Double> singleValues = new HashSet<Double>();
for (Double value : values)
{
singleValues.add(value);
}
System.out.println("singleValues: "+singleValues);
// now convert it into double array
Double[] dValues = singleValues.toArray(new Double[]{});
}
Here's another alternative without the use of sets, only primitive types:
public static double [] removeDuplicates(double arr[]) {
double [] tempa = new double[arr.length];
int uniqueCount = 0;
for (int i=0;i<arr.length;i++) {
boolean unique = true;
for (int j=0;j<uniqueCount && unique;j++) {
if (arr[i] == tempa[j]) {
unique = false;
}
}
if (unique) {
tempa[uniqueCount++] = arr[i];
}
}
return Arrays.copyOf(tempa, uniqueCount);
}
It does require a temporary array of double objects on the way towards getting your actual result.
You can use a set for removing multiples.