Get unique elements from Java array - where's the mistake? [duplicate] - java

This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 12 months ago.
I'm just a beginner and I'm trying to write a method returning only unique elements from Java array. What's wrong with this code? Could you please point my mistakes and help me correct them? I've got no idea what to do with it.
P.S. I know I could use packages, but it has to be done in the simplest way.
public static void main(String[] args) {
int[] arr = {1, 1, 2, 3};
int[] items = returnNonRepeated(arr);
System.out.print(items);
}
public static int[] returnNonRepeated(int[] arr) {
int[] temp = new int[0];
int n = 0;
for (int i = 0; i < arr.length; i++) {
if (i == 0) {
temp[i] = arr[i];
} else {
if (arr[i] != arr[i - 1]) {
temp[numbersCount] = arr[i];
numbersCount++;
}
}
}
return temp;
}
}

I know it's not code golf here, but:
if you want to keep only unique values (like a Set would do), you can use a "one-liner". You don't have to implement loops.
public static void main(String[] args) {
int[] dupes = {0, 1, 2, 1, 3, 2, 3};
int[] uniques = Arrays.stream(dupes) // stream ints
.boxed() // make Integer of int
.collect(Collectors.toSet()) // collect into set to remove duplicates
.stream() // stream Integers
.mapToInt(Integer::intValue) // make int of Integer
.toArray(); // and back into an array
System.out.println(Arrays.toString(uniques));
}
Please not that you have to use java.util.Arrays.toString() to get useful output in the last statement. With your variant it will print only something like "[I#531be3c5" which denotes that it is an array of int, but says nothing about the contents.
Nevertheless - if you want to understand, how arrays and loops work, the looping solution is better!

I'm not sure if you mean non-repeat or unique
But here is a method for checking for duplicates:
public static int[] returnUniqueArray(int[] arr) {
int dupes = new int[arr.length]; // The most dupes you could have is the length of the input
int numberOfDupes = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if(arr[i] == arr[j]) {
dupes[numberOfDupes] = arr[i];
numberOfDupes++;
}
}
}
return dupes;
}
This loops round the arr array twice, therefore comparing every variable in arr to every other variable. If they are the same, it adds that value to a new array.
You could also do similar for non-repeat:
public static int[] returnNonRepeatArray(int[] arr) {
int dupes = new int[arr.length];
int numberOfDupes = 0;
for (int i = 0; i < arr.length - 1; i++) {
if(arr[i] == arr[i+1]) {
dupes[numberOfDupes] = arr[i];
numberOfDupes++;
}
}
return dupes;
}
This loops round the arr array once, but does not check the last item (-1 in the for loop). It then compares the item against the next item, if they are the same it adds that to the dupes.

public static void main(String[] args) {
int[] arr = {1, 1, 2, 2, 3, 4, 5, 5, 5, 6};
int[] items = returnNonRepeated(arr);
System.out.print(Arrays.toString(items));
}
public static int[] returnNonRepeated(int[] arr) {
int[] temp = new int[arr.length];
int numbersCount = 1;
for (int i = 0; i < arr.length; i++) {
if (i == 0) {
uniques[numbersCount] = arr[i];
numbersCount++;
} else {
if (arr[i] != arr[i - 1]) {
uniques[numbersCount] = arr[i];
numbersCount++;
}
}
}
return uniques;
}

Related

How to remove duplicate elements from a sorted array

Given a sorted array A of size N, delete all the duplicates elements from A.
Note: Don't use set or HashMap to solve the problem.
example:
Input:
N = 5
Array = {2, 2, 2, 2, 2}
Output:
2
Explanation: After removing all the duplicates
only one instance of 2 will remain.
I have tried the below code. Please tell me what's wrong with the code?
int remove_duplicate(int arr[],int N){
// code here
int index=0;
for(int i=1;i<N;i++){
if(arr[i]!=arr[i-1]){
arr[index]=arr[i-1];
index++;
}
}
return index+1;
}
You could replace some duplicate elements and set the length at the end.
This approach mutates the array.
const
remove_duplicate = array => {
let j = 0;
for (let i = 0; i < array.length; i++) {
if (array[j - 1] !== array[i]) array[j++] = array[i];
}
array.length = j;
return array;
};
console.log(...remove_duplicate([2, 2, 2]));
console.log(...remove_duplicate([1, 1, 2, 2, 3, 4, 5, 5]));
Overkill using binary tree
BinaryTree binaryTree = new BinaryTree();
for (int i = 0; i < n; i++){
//add or insert function need to check that the key isn't in the stracture
binaryTree.Add(arr[i]);
}
binaryTree.TraverseInOrder(binaryTree.Root);
You need to implement some of the classes.
Check this example:
c-binary-search-tree-implementation
For more on Inorder output for binaryTree:
binary-tree-from-inorder-traversal
Look here: https://www.geeksforgeeks.org/duplicates-array-using-o1-extra-space-set-2/
// Java program to print all elements that
// appear more than once.
import java.util.*;
class GFG {
// function to find repeating elements
static void printRepeating(int arr[], int n)
{
// First check all the values that are
// present in an array then go to that
// values as indexes and increment by
// the size of array
for (int i = 0; i < n; i++)
{
int index = arr[i] % n;
arr[index] += n;
}
// Now check which value exists more
// than once by dividing with the size
// of array
for (int i = 0; i < n; i++)
{
if ((arr[i] / n) >= 2)
System.out.println(i + " ");
}
}
// Driver code
public static void main(String args[])
{
int arr[] = { 1, 6, 3, 1, 3, 6, 6 };
int arr_size = arr.length;
System.out.println("The repeating elements are: ");
// Function call
printRepeating(arr, arr_size);
}
}
Try this:
int remove_duplicate(int arr[],int N){
int index=0;
for(int i=1;i<N;i++){
if(arr[i]!=arr[index]){ //change index
index++; //swapt next line
arr[index]=arr[i];
}
}
return index+1;
}
you can check my answer here - and it works perfectly
https://stackoverflow.com/a/32931932/3052125
Here is the main logic to remove the duplicates - arr is the sorted array provided to you with duplicate elements -
// Logic for removing the duplicate elements
int compare = 0;
arr[compare] = arr[0];
for (int i = 1; i < size; i++) {
if (arr[compare] != arr[i]) {
compare++;
arr[compare] = arr[i];
}
}
Given a sorted array A of size N, delete all the duplicates elements from A
Well, that implies returning an array with duplicates deleted.
int[] v = { 1, 1, 1, 2, 2, 2, 2,3 };
v = remove_duplicates(v);
System.out.println(Arrays.toString(v));
prints
[1, 2, 3]
The method. This works by copying the unique values toward the front of the passed array. So this does alter that array.
public static int[] remove_duplicates(int[] v) {
int current = 0;
for (int i = 0; i < v.length; i++) {
if (v[i] != v[current]) {
v[++current] = v[i];
}
}
// Now return the front portion of the array that contains the distinct
// values. You could also just create a new array and copy the elements
// using a loop.
return Arrays.copyOf(v, current+1);
}

Two Sum LeetCode Java Questions

I am attempting a Java mock interview on LeetCode. I have the following problem:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
I was attempting to implement a recursive solution. However, I am receiving errors upon trying to run my code.
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] sumnums = nums.clone();
//int[2] sol = {0,1};
int[] sol = new int[]{0,1};
sol = new int[2];
int j=sumnums.length;
int t=target;
for(int i=0;i<sumnums.length;i++){
if ((sumnums[i]+sumnums[j])==t){
sol[0]=i;
sol[1]=j;
//return sol;
}
}
j=j-1;
twoSum(sumnums,t);
return sol;
}
}
Error(s):
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Solution.twoSum(Solution.java:12)
at __DriverSolution__.__helper__(__Driver__.java:8)
at __Driver__.main(__Driver__.java:54)
It appears to me the error may have to do with the following line of code:
if ((sumnums[i]+sumnums[j])==t){
Therefore, I am wondering if this is a syntax related error. I am attempting to check to see if two numbers add up to a different number.
Since this is a naive attempt at a recursive solution, I am happy to take any other criticism. But I am mostly concerned with getting my attempt at this problem to work and run with all testcases.
Thanks.
METHOD 1. Naive approach: Use two for loops
The naive approach is to just use two nested for loops and check if the sum of any two elements in the array is equal to the given target.
Time complexity: O(n^2)
// Time complexity: O(n^2)
private static int[] findTwoSum_BruteForce(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return new int[] { i, j };
}
}
}
return new int[] {};
}
METHOD 2. Use a HashMap (Most efficient)
You can use a HashMap to solve the problem in O(n) time complexity. Here are the steps:
Initialize an empty HashMap.
Iterate over the elements of the array.
For every element in the array -
If the element exists in the Map, then check if it’s the complement (target - element) also exists in the Map or not. If the complement exists then return the indices of the current element and the complement.
Otherwise, put the element in the Map, and move to the next iteration.
Time complexity: O(n)
// Time complexity: O(n)
private static int[] findTwoSum(int[] nums, int target) {
Map<Integer, Integer> numMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (numMap.containsKey(complement)) {
return new int[] { numMap.get(complement), i };
} else {
numMap.put(nums[i], i);
}
}
return new int[] {};
}
METHOD 3. Use Sorting along with the two-pointer sliding window approach
There is another approach which works when you need to return the numbers instead of their indexes. Here is how it works:
Sort the array.
Initialize two variables, one pointing to the beginning of the array (left) and another pointing to the end of the array (right).
Loop until left < right, and for each iteration
if arr[left] + arr[right] == target, then return the indices.
if arr[left] + arr[right] < target, increment the left index.
else, decrement the right index.
This approach is called the two-pointer sliding window approach. It is a very common pattern for solving array related problems.
Time complexity: O(n*log(n))
// Time complexity: O(n*log(n))
private static int[] findTwoSum_Sorting(int[] nums, int target) {
Arrays.sort(nums);
int left = 0;
int right = nums.length - 1;
while(left < right) {
if(nums[left] + nums[right] == target) {
return new int[] {nums[left], nums[right]};
} else if (nums[left] + nums[right] < target) {
left++;
} else {
right--;
}
}
return new int[] {};
}
Why not use a HashMap? Here is how it will work. We will iterate through the array and check if the target - nums[i] exists in the map. If not, we will store Key, Value as the number and its index respectively i.e K = nums[i], V = i
Here is how it will work:
Consider nums = [2, 7, 11, 15], target = 9
We will start iterating the array
First comes 2. Here we will check ( 9 - 2 ) i.e 7 does not exist in the hashmap, so we will store 2 as key and its index 0 as its value
Then, comes 7. Here we will check ( 9 - 7 ) i.e 2 which exists in the map and so we will return the index of 2 and index of 7 i.e returning [ 0, 1 ]
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++)
{
if(map.containsKey(target - nums[i]))
{
return new int[] {map.get(target-nums[i]),i};
}
else
map.put(nums[i],i);
}
return new int[] {-1,-1};
}
As you mentioned
First comes 2. Here we will check ( 9 - 2 ) i.e 7 does not exist in the hashmap
actually 7 does exist in the HashMap right
nums = [2, 7, 11, 15], target = 9
public static int[] twoSum(int[] nums, int target) {
int[] sumnums = nums.clone();
//int[2] sol = {0,1};
int[] sol = new int[]{0,1};
sol = new int[2];
int j=sumnums.length; // Every recursion j will be initialized as sumnums.length instead of J-1
int t=target;
for(int i=0;i<sumnums.length;i++){
// if ((sumnums[i]+sumnums[j])==t){
// Remember that Java arrays start at index 0, so this value(sumnums[j]) is not exist in the array.
if ((sumnums[i]+sumnums[j-1])==t){
sol[0]=i;
sol[1]=j;
return sol;
}
}
j=j-1;
twoSum(sumnums,t);
return sol;
}
One of the many possible solutions:
public class TwoSumIndex {
public static void main(String... args) {
int[] arr = {2, 7, 11, 15, 9, 0, 2, 7};
System.out.println(findTwoSums(arr, 9));
}
private static List<List<Integer>> findTwoSums(int[] arr, int target) {
Set<Integer> theSet = Arrays.stream(arr).mapToObj(Integer::valueOf).collect(Collectors.toSet());
List<Integer> arrList = Arrays.stream(arr).mapToObj(Integer::valueOf).collect(Collectors.toList());
List<Pair<Integer, Integer>> theList = new ArrayList<>();
List<Integer> added = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
int a = target - arr[i];
if (theSet.contains(a) && added.indexOf(i) < 0) { // avoid duplicates;
Integer theOther = arrList.indexOf(a);
theList.add(new Pair(i, theOther));
added.add(i);
added.add(theOther);
}
}
return theList.stream().map(pair -> new ArrayList<>(Arrays.asList(pair.getKey(), pair.getValue())))
.collect(Collectors.toList());
}
}
There are several things you need to know:
duplicates in the input array are allowed;
un-ordered array in the input is allowed;
no index pair duplicate in the output;
time complexity is theoretically O(N^2) but actually will be much lower since theSet.contains(a) O(logN) will filter out all failed indexes and then do the index duplicate O(N) checking, so the actual time complexity should be O(NlogN);
The output for the demo:
[[0, 1], [4, 5], [6, 1], [7, 0]]
I use the simpler approch
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indices= new int[2];
int len=nums.length;
for(int i=0; i<len; i++){
for(int j=i+1; j<len;j++){
if((nums[i]+nums[j])==target){
indices[0] = i;
indices[1] = j;
return indices;
}
}
}
return null;
}
}
Complete code for beginners
//Predefined values
import java.util.Arrays;
public class TwoSum {
public static void main(String args[]) {
Solution solution = new Solution();
int target = 9;
int num[] = {2, 7, 11, 15};
num = solution.twoSum(num, target);
System.out.println(Arrays.toString(num));
}
}
class Solution {
public int[] twoSum(int[] nums, int target) {
int result[] = new int[2];
int sum;
for (int i = 0; i + 1 < nums.length; i++) {
// adding the alternate numbers
sum = nums[i] + nums[i + 1];
if (sum == target) {
result[0] = i;
result[1] = i + 1;
return result;
}
}
return null;
}
}
************************************************************************
//User-defined
import java.util.Arrays;
import java.util.Scanner;
/**
*
* #author shelc
*/
public class TwoSum {
public static void main(String[] args) {
Solution solution = new Solution();
Scanner scanner = new Scanner(System.in);
int n;
System.out.print("Enter the number of elements : ");
n = scanner.nextInt();
int array[] = new int[10];
System.out.println("Enter the array elemets : ");
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int target;
System.out.println("Enter the target : ");
target = scanner.nextInt();
int nums[] = solution.twoSum(array, target);
System.out.println(Arrays.toString(nums));
}
}
class Solution {
public int[] twoSum(int nums[], int target) {
int result[] = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if ((nums[i] + nums[j]) == target) {
result[0] = i;
result[1] = j;
return result;
}
}
}
return null;
}
}
public static int[] twoSum(int[] nums, int target) {
int[] arr = new int[2];
int arrIndex =0;
for(int i =0; i<nums.length; i++){
for(int j = 0;j<nums.length-1;j++){
if( i!=j) {// don't check to itself
if (nums[i] + nums[j] == target) {
arr[arrIndex] = i;
arr[arrIndex + 1] = j;
break;
}
}
}
}
Arrays.sort(arr);
return arr;
}

Expanding an array to represent an index as many times as the magnitude of original value

Example: expand(new int[]{3, 2, 5}) -> {0, 0, 0, 1, 1, 2, 2, 2, 2, 2}
I am trying to have it make a a new array to print the index of say 3, 3 times. So 3 would be 0,0,0.
public static int[] expand(int[] input) {
int c = 0;
int[] myArray = new int[sum(input)];
if(input.length == 0){
return new int[0];
}
for(int i = 0; i < input.length; i++) {
int a = input[i];
for(int j = c; j < a; j++) {
c += j;
myArray[j] = i;
}
}
return myArray;
}
Currently this only partially works and I cant seem to figure out how to go through the full array properly. In addition, index zero seems to get skipped.
You were close! It seems that you just need to modify your nested for-loop slightly:
for (int j = 0; j < a; j++) {
myArray[c++] = i;
}
Seeing as you're using c to keep track of the current index, this simply sets the element at index c to i and increments c. You can also remove a and use input[i] in place of it.
Note: It is easier to start j from 0 rather than from c.
Functional method
public class Main {
public static void main(final String... args) {
int[] items = expand(new int[]{3, 2, 5});
System.out.println(Arrays.toString(items));
}
public static int[] expand(int[] input) {
return IntStream.range(0, input.length)
.flatMap(p -> IntStream.generate(() -> p).limit(input[p]))
.toArray();
}
}
This makes a stream of the index, and for each item takes that many of the index, putting all of them into an array

There are other options to reverse an input numbers on an array? [duplicate]

I am trying to reverse an int array in Java.
This method does not reverse the array.
for(int i = 0; i < validData.length; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
What is wrong with it?
To reverse an int array, you swap items up until you reach the midpoint, like this:
for(int i = 0; i < validData.length / 2; i++)
{
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
The way you are doing it, you swap each element twice, so the result is the same as the initial list.
With Commons.Lang, you could simply use
ArrayUtils.reverse(int[] array)
Most of the time, it's quicker and more bug-safe to stick with easily available libraries already unit-tested and user-tested when they take care of your problem.
Collections.reverse(Arrays.asList(yourArray));
java.util.Collections.reverse() can reverse java.util.Lists and java.util.Arrays.asList() returns a list that wraps the the specific array you pass to it, therefore yourArray is reversed after the invocation of Collections.reverse().
The cost is just the creation of one List-object and no additional libraries are required.
A similar solution has been presented in the answer of Tarik and their commentors, but I think this answer would be more concise and more easily parsable.
public class ArrayHandle {
public static Object[] reverse(Object[] arr) {
List<Object> list = Arrays.asList(arr);
Collections.reverse(list);
return list.toArray();
}
}
I think it's a little bit easier to follow the logic of the algorithm if you declare explicit variables to keep track of the indices that you're swapping at each iteration of the loop.
public static void reverse(int[] data) {
for (int left = 0, right = data.length - 1; left < right; left++, right--) {
// swap the values at the left and right indices
int temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
I also think it's more readable to do this in a while loop.
public static void reverse(int[] data) {
int left = 0;
int right = data.length - 1;
while( left < right ) {
// swap the values at the left and right indices
int temp = data[left];
data[left] = data[right];
data[right] = temp;
// move the left and right index pointers in toward the center
left++;
right--;
}
}
Use a stream to reverse
There are already a lot of answers here, mostly focused on modifying the array in-place. But for the sake of completeness, here is another approach using Java streams to preserve the original array and create a new reversed array:
int[] a = {8, 6, 7, 5, 3, 0, 9};
int[] b = IntStream.rangeClosed(1, a.length).map(i -> a[a.length-i]).toArray();
Guava
Using the Google Guava library:
Collections.reverse(Ints.asList(array));
In case of Java 8 we can also use IntStream to reverse the array of integers as:
int[] sample = new int[]{1,2,3,4,5};
int size = sample.length;
int[] reverseSample = IntStream.range(0,size).map(i -> sample[size-i-1])
.toArray(); //Output: [5, 4, 3, 2, 1]
for(int i=validData.length-1; i>=0; i--){
System.out.println(validData[i]);
}
Simple for loop!
for (int start = 0, end = array.length - 1; start <= end; start++, end--) {
int aux = array[start];
array[start]=array[end];
array[end]=aux;
}
If working with data that is more primitive (i.e. char, byte, int, etc) then you can do some fun XOR operations.
public static void reverseArray4(int[] array) {
int len = array.length;
for (int i = 0; i < len/2; i++) {
array[i] = array[i] ^ array[len - i - 1];
array[len - i - 1] = array[i] ^ array[len - i - 1];
array[i] = array[i] ^ array[len - i - 1];
}
}
This will help you
int a[] = {1,2,3,4,5};
for (int k = 0; k < a.length/2; k++) {
int temp = a[k];
a[k] = a[a.length-(1+k)];
a[a.length-(1+k)] = temp;
}
This is how I would personally solve it. The reason behind creating the parametrized method is to allow any array to be sorted... not just your integers.
I hope you glean something from it.
#Test
public void reverseTest(){
Integer[] ints = { 1, 2, 3, 4 };
Integer[] reversedInts = reverse(ints);
assert ints[0].equals(reversedInts[3]);
assert ints[1].equals(reversedInts[2]);
assert ints[2].equals(reversedInts[1]);
assert ints[3].equals(reversedInts[0]);
reverseInPlace(reversedInts);
assert ints[0].equals(reversedInts[0]);
}
#SuppressWarnings("unchecked")
private static <T> T[] reverse(T[] array) {
if (array == null) {
return (T[]) new ArrayList<T>().toArray();
}
List<T> copyOfArray = Arrays.asList(Arrays.copyOf(array, array.length));
Collections.reverse(copyOfArray);
return copyOfArray.toArray(array);
}
private static <T> T[] reverseInPlace(T[] array) {
if(array == null) {
// didn't want two unchecked suppressions
return reverse(array);
}
Collections.reverse(Arrays.asList(array));
return array;
}
Your program will work for only length = 0, 1.
You can try :
int i = 0, j = validData.length-1 ;
while(i < j)
{
swap(validData, i++, j--); // code for swap not shown, but easy enough
}
There are two ways to have a solution for the problem:
1. Reverse an array in space.
Step 1. Swap the elements at the start and the end index.
Step 2. Increment the start index decrement the end index.
Step 3. Iterate Step 1 and Step 2 till start index < end index
For this, the time complexity will be O(n) and the space complexity will be O(1)
Sample code for reversing an array in space is like:
public static int[] reverseAnArrayInSpace(int[] array) {
int startIndex = 0;
int endIndex = array.length - 1;
while(startIndex < endIndex) {
int temp = array[endIndex];
array[endIndex] = array[startIndex];
array[startIndex] = temp;
startIndex++;
endIndex--;
}
return array;
}
2. Reverse an array using an auxiliary array.
Step 1. Create a new array of size equal to the given array.
Step 2. Insert elements to the new array starting from the start index, from the
given array starting from end index.
For this, the time complexity will be O(n) and the space complexity will be O(n)
Sample code for reversing an array with auxiliary array is like:
public static int[] reverseAnArrayWithAuxiliaryArray(int[] array) {
int[] reversedArray = new int[array.length];
for(int index = 0; index < array.length; index++) {
reversedArray[index] = array[array.length - index -1];
}
return reversedArray;
}
Also, we can use the Collections API from Java to do this.
The Collections API internally uses the same reverse in space approach.
Sample code for using the Collections API is like:
public static Integer[] reverseAnArrayWithCollections(Integer[] array) {
List<Integer> arrayList = Arrays.asList(array);
Collections.reverse(arrayList);
return arrayList.toArray(array);
}
There are some great answers above, but this is how I did it:
public static int[] test(int[] arr) {
int[] output = arr.clone();
for (int i = arr.length - 1; i > -1; i--) {
output[i] = arr[arr.length - i - 1];
}
return output;
}
It is most efficient to simply iterate the array backwards.
I'm not sure if Aaron's solution does this vi this call Collections.reverse(list); Does anyone know?
public void getDSCSort(int[] data){
for (int left = 0, right = data.length - 1; left < right; left++, right--){
// swap the values at the left and right indices
int temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
Solution with o(n) time complexity and o(1) space complexity.
void reverse(int[] array) {
int start = 0;
int end = array.length - 1;
while (start < end) {
int temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end--;
}
}
public void display(){
String x[]=new String [5];
for(int i = 4 ; i > = 0 ; i-- ){//runs backwards
//i is the nums running backwards therefore its printing from
//highest element to the lowest(ie the back of the array to the front) as i decrements
System.out.println(x[i]);
}
}
Wouldn't doing it this way be much more unlikely for mistakes?
int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] temp = new int[intArray.length];
for(int i = intArray.length - 1; i > -1; i --){
temp[intArray.length - i -1] = intArray[i];
}
intArray = temp;
Using the XOR solution to avoid the temp variable your code should look like
for(int i = 0; i < validData.length; i++){
validData[i] = validData[i] ^ validData[validData.length - i - 1];
validData[validData.length - i - 1] = validData[i] ^ validData[validData.length - i - 1];
validData[i] = validData[i] ^ validData[validData.length - i - 1];
}
See this link for a better explanation:
http://betterexplained.com/articles/swap-two-variables-using-xor/
2 ways to reverse an Array .
Using For loop and swap the elements till the mid point with time complexity of O(n/2).
private static void reverseArray() {
int[] array = new int[] { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < array.length / 2; i++) {
int temp = array[i];
int index = array.length - i - 1;
array[i] = array[index];
array[index] = temp;
}
System.out.println(Arrays.toString(array));
}
Using built in function (Collections.reverse())
private static void reverseArrayUsingBuiltInFun() {
int[] array = new int[] { 1, 2, 3, 4, 5, 6 };
Collections.reverse(Ints.asList(array));
System.out.println(Arrays.toString(array));
}
Output : [6, 5, 4, 3, 2, 1]
public static void main(String args[]) {
int [] arr = {10, 20, 30, 40, 50};
reverse(arr, arr.length);
}
private static void reverse(int[] arr, int length) {
for(int i=length;i>0;i--) {
System.out.println(arr[i-1]);
}
}
below is the complete program to run in your machine.
public class ReverseArray {
public static void main(String[] args) {
int arr[] = new int[] { 10,20,30,50,70 };
System.out.println("reversing an array:");
for(int i = 0; i < arr.length / 2; i++){
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
For programs on matrix using arrays this will be the good source.Go through the link.
private static int[] reverse(int[] array){
int[] reversedArray = new int[array.length];
for(int i = 0; i < array.length; i++){
reversedArray[i] = array[array.length - i - 1];
}
return reversedArray;
}
Here is a simple implementation, to reverse array of any type, plus full/partial support.
import java.util.logging.Logger;
public final class ArrayReverser {
private static final Logger LOGGER = Logger.getLogger(ArrayReverser.class.getName());
private ArrayReverser () {
}
public static <T> void reverse(T[] seed) {
reverse(seed, 0, seed.length);
}
public static <T> void reverse(T[] seed, int startIndexInclusive, int endIndexExclusive) {
if (seed == null || seed.length == 0) {
LOGGER.warning("Nothing to rotate");
}
int start = startIndexInclusive < 0 ? 0 : startIndexInclusive;
int end = Math.min(seed.length, endIndexExclusive) - 1;
while (start < end) {
swap(seed, start, end);
start++;
end--;
}
}
private static <T> void swap(T[] seed, int start, int end) {
T temp = seed[start];
seed[start] = seed[end];
seed[end] = temp;
}
}
Here is the corresponding Unit Test
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;
public class ArrayReverserTest {
private Integer[] seed;
#Before
public void doBeforeEachTestCase() {
this.seed = new Integer[]{1,2,3,4,5,6,7,8};
}
#Test
public void wholeArrayReverse() {
ArrayReverser.<Integer>reverse(seed);
assertThat(seed[0], is(8));
}
#Test
public void partialArrayReverse() {
ArrayReverser.<Integer>reverse(seed, 1, 5);
assertThat(seed[1], is(5));
}
}
Here is what I've come up with:
// solution 1 - boiler plated
Integer[] original = {100, 200, 300, 400};
Integer[] reverse = new Integer[original.length];
int lastIdx = original.length -1;
int startIdx = 0;
for (int endIdx = lastIdx; endIdx >= 0; endIdx--, startIdx++)
reverse[startIdx] = original[endIdx];
System.out.printf("reverse form: %s", Arrays.toString(reverse));
// solution 2 - abstracted
// convert to list then use Collections static reverse()
List<Integer> l = Arrays.asList(original);
Collections.reverse(l);
System.out.printf("reverse form: %s", l);
static int[] reverseArray(int[] a) {
int ret[] = new int[a.length];
for(int i=0, j=a.length-1; i<a.length && j>=0; i++, j--)
ret[i] = a[j];
return ret;
}
public static int[] reverse(int[] array) {
int j = array.length-1;
// swap the values at the left and right indices //////
for(int i=0; i<=j; i++)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
j--;
}
return array;
}
public static void main(String []args){
int[] data = {1,2,3,4,5,6,7,8,9};
reverse(data);
}

How to remove duplicates from a list using an auxiliary array in Java?

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.

Categories

Resources