I have an int array as [2,4,1,0,0,3] and need to obtain from that an array of the indexes in ascending order, means [3,4,2,0,5,1].
I tried to resolve this by using a sorted array to get the numbers in order, then iterating over the original array to find the index when a match happens. As follows:
public class IndexAscendingSorter {
public static void main (String[] args) {
int[] array = {2,4,1,0,0,3};
IndexAscendingSorter finder = new IndexAscendingSorter();
int[] indixes = finder.orderIndexAscending(array);
System.out.println("Indexes of the array in ascending order: " +
Arrays.toString(indixes));
}
public int[] orderIndexAscending(int[] array) {
int[] minimumIndexes = new int[array.length];
int[] sortedArray = array.clone();
Arrays.sort(sortedArray);
for (int index = 0; index < array.length; index++){
int minIndex = 0;
for (int number : array) {
if (number == sortedArray[index]) {
minimumIndexes[index] = minIndex;
break;
}
minIndex++;
}
}
return minimumIndexes;
}
}
The problem is that for same numbers don't return the correct indexes, the output of executing that code is:
Indexes of the array in ascending order: [3, 3, 2, 0, 5, 1]
The second value array[1] should have been 4 instead of 3. Does anyone know how can I improve this?
Continuing with your approach, a quick solution would be to use a hash set where you will add the indexes you have already used, and then can check if it is a repeated index. Just change the orderIndexAscending() function to:
public int[] orderIndexAscending(int[] array) {
int[] minimumIndexes = new int[array.length];
int[] sortedArray = array.clone();
Arrays.sort(sortedArray);
Set<Integer> savedIndexes = new HashSet<>();
for (int index = 0; index < array.length; index++){
int minIndex = 0;
// Add the index in ascending order, we need to keep the indexes already
// saved, so won't miss indexes from repeted values
for (int number : array) {
if (number == sortedArray[index] && !savedIndexes.contains(minIndex)) {
savedIndexes.add(minIndex);
minimumIndexes[index] = minIndex;
break;
}
minIndex++;
}
}
return minimumIndexes;
}
}
Pair the numbers with their original indices:
[2,4,1,0,0,3] => [[2,0],[4,1],[1,2],[0,3],[0,4],[3,5]]]
Then sort by the original value:
=> [[0,3],[0,4],[1,2],[2,0],[3,5],[4,1]]]
And lastly extract the indices:
=> [3,4,2,0,5,1]
Initialize the index array to the Integers 0, 1, 2, 3, ..., then sort it, using a custom comperator that looks up the corresponding array values and compares them.
for (int index = 0; index < array.length; index++){
int minIndex = 0;
for (int number : array) {
if (number == sortedArray[index]) {
minimumIndexes[index] = minIndex;
array[minIndex]=Integer.MAX_VALUE;
break;
}
minIndex++;
}
}
You can simply update already visited value with any value never present in the array.
You may simply update the value that has already been visited with any value that is not present in the array.
for (int index = 0; index < array.length; index++){
int minIndex = 0;
for (int number : array) {
if (number == sortedArray[index]) {
minimumIndexes[index] = minIndex;
array[minIndex]=Integer.MAX_VALUE;
break;
}
minIndex++;
}
}
Related
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);
}
Wrote some code to try to find the maximum element in an un-ordered array and then delete it from the array. My first loop has the logic to find the maximum element while the second loop should take in the variable from the first loop, look ahead one space and then insert into the max element.
My below code seems to work for my second idea .. but does not find the right max array element.
My array has the following values {6, 3, 5, 2, 7, 9, 4}. It is finding the max array element to be 7 .. it should be 9.
public void deleteMax() {
// set value for comparison starting from the beginning of the array
int arrayMax = arr[0];
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
for (int k = i; k < nElems; k++) {
arr[k] = arr[k + 1];
nElems--;
break;
}
}
}
}
why not use jQuery $.grep & Math.max like:
var arr = [6, 3, 5, 2, 7, 9, 4];
var maxNum = Math.max.apply(null, arr);
var newArr = $.grep( arr, function( n ) {
return n != maxNum;
});
console.log(newArr);
Fiddle
EDIT:
Well didn't realize you're using Java as the question showed in JavaScript section...
in Java, You can find max number in array like
int maxNum = arr.get(0); // get the first number in array
for (int i = 1; i < arr.length; i++) {
if ( arr.get(i) > maxNum) {
maxNum = array.get(i);
}
}
arr.remove(maxNum);
Well,, you don't need any second loop.
Only one loop and two variables called, f.ex. MaxElementPosition and MaxElementValue, which are updated every time inside the loop if the number on this position is greater than the last MaxElementValue, update both value and position.
While the loop you do need the value for comparing. In the end you only need the position.
Your inner loop is irrelevant, you only have a 1D array, so it makes no sense to do any inner iteration.
If you insist on performing no sorting on the array, then you could do something like this:
public void deleteMax() {
// set value for comparison starting from the beginning of the array
int arrayMax = arr[0];
int maxIndex = 0;
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
maxIndex = i;
}
}
arr.remove(maxIndex);
}
Once the for loop finishes, we remove the item at maxIndex
#Alex is on the right track, but there is no remove function that can be called on an array in java. All that you need is the variable maxIndex that he gets, which of course will be the first occurence of this maximum, so if you need to remove every occurence of the maximum, that would be a different issue. So once you use #Alex code:
int arrayMax = arr[0];
int maxIndex = 0;
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
maxIndex = i;
}
}
This would be much easier if instead of an array, you were to use an ArrayList, in which case the code would look like:
int arrayMax = arr.get(0);
int maxIndex = 0;
for (int i = 0; i < nElems; i++) {
if (arr[i] > arrayMax) {
arrayMax = arr[i];
maxIndex = i;
}
}
arr.remove(maxIndex);
Otherwise you would have to create a temp array to remove the value:
int[] temp = new int[arr.length-1];
for(int i = 0, index = 0; index < nElems; i++, index++)
{
if(index == maxIndex) index++;
temp[i] = arr[index];
}
arr = temp;
I have to write a method that takes an array of ints that is already sorted in numerical order then remove all the duplicate numbers and return an array of just the numbers that have no duplicates. That array must then be printed out so I can't have any null pointer exceptions. The method has to be in O(n) time, can't use vectors or hashes. This is what I have so far but it only has the first couple numbers in order without duplicates and then just puts the duplicates in the back of the array. I can't create a temporary array because it gives me null pointer exceptions.
public static int[] noDups(int[] myArray) {
int j = 0;
for (int i = 1; i < myArray.length; i++) {
if (myArray[i] != myArray[j]) {
j++;
myArray[j] = myArray[i];
}
}
return myArray;
}
Since this seems to be homework I don't want to give you the exact code, but here's what to do:
Do a first run through of the array to see how many duplicates there are
Create a new array of size (oldSize - duplicates)
Do another run through of the array to put the unique values in the new array
Since the array is sorted, you can just check if array[n] == array[n+1]. If not, then it isn't a duplicate. Be careful about your array bounds when checking n+1.
edit: because this involves two run throughs it will run in O(2n) -> O(n) time.
Tested and works (assuming the array is ordered already)
public static int[] noDups(int[] myArray) {
int dups = 0; // represents number of duplicate numbers
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is the same
if (myArray[i] == myArray[i - 1])
dups++; // add one to number of duplicates
}
// create return array (with no duplicates)
// and subtract the number of duplicates from the original size (no NPEs)
int[] returnArray = new int[myArray.length - dups];
returnArray[0] = myArray[0]; // set the first positions equal to each other
// because it's not iterated over in the loop
int count = 1; // element count for the return array
for (int i = 1; i < myArray.length; i++)
{
// if current number in original array is not the same as the one before
if (myArray[i] != myArray[i-1])
{
returnArray[count] = myArray[i]; // add the number to the return array
count++; // continue to next element in the return array
}
}
return returnArray; // return the ordered, unique array
}
My previous answer to this problem with used an Integer List.
Not creating a new array will surely result in nulls all over the initial array. Therefore create a new array for storing the unique values from the initial array.
How do you check for unique values? Here's the pseudo code
uniq = null
loop(1..arraysize)
if (array[current] == uniq) skip
else store array[current] in next free index of new array; uniq = array[current]
end loop
Also as others mentioned get the array size by initial scan of array
uniq = null
count = 0
loop(1..arraysize)
if (array[current] == uniq) skip
else uniq = array[current] and count++
end loop
create new array of size count
public static int[] findDups(int[] myArray) {
int numOfDups = 0;
for (int i = 0; i < myArray.length-1; i++) {
if (myArray[i] == myArray[i+1]) {
numOfDups++;
}
}
int[] noDupArray = new int[myArray.length-numOfDups];
int last = 0;
int x = 0;
for (int i = 0; i < myArray.length; i++) {
if(last!=myArray[i]) {
last = myArray[i];
noDupArray[x++] = last;
}
}
return noDupArray;
}
public int[] noDups(int[] arr){
int j = 0;
// copy the items without the dups to res
int[] res = new int[arr.length];
for(int i=0; i<arr.length-2; i++){
if(arr[i] != arr[i+1]){
res[j] = arr[i];
j++;
}
}
// copy the last element
res[j]=arr[arr.length-1];
j++;
// now move the result into a compact array (exact size)
int[] ans = new int[j];
for(int i=0; i<j; i++){
ans[i] = res[i];
}
return ans;
}
First loop is O(n) and so is the second loop - which totals in O(n) as requested.
I have an array of size 1000. How can I find the indices (indexes) of the five maximum elements?
An example with setup code and my attempt are displayed below:
Random rand = new Random();
int[] myArray = new int[1000];
int[] maxIndices = new int[5];
int[] maxValues = new int[5];
for (int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt();
}
for (int i = 0; i < 5; i++) {
maxIndices[i] = i;
maxValues[i] = myArray[i];
}
for (int i = 0; i < maxIndices.length; i++) {
for (int j = 0; j < myArray.length; j++) {
if (myArray[j] > maxValues[i]) {
maxIndices[i] = j;
maxValues[i] = myArray[j];
}
}
}
for (int i = 0; i < maxIndices.length; i++) {
System.out.println("Index: " + maxIndices[i]);
}
I know the problem is that it is constantly assigning the highest maximum value to all the maximum elements. I am unsure how to remedy this because I have to preserve the values and the indices of myArray.
I don't think sorting is an option because I need to preserve the indices. In fact, it is the indices that I need specifically.
Sorry to answer this old question but I am missing an implementation which has all following properties:
Easy to read
Performant
Handling of multiple same values
Therefore I implemented it:
private int[] getBestKIndices(float[] array, int num) {
//create sort able array with index and value pair
IndexValuePair[] pairs = new IndexValuePair[array.length];
for (int i = 0; i < array.length; i++) {
pairs[i] = new IndexValuePair(i, array[i]);
}
//sort
Arrays.sort(pairs, new Comparator<IndexValuePair>() {
public int compare(IndexValuePair o1, IndexValuePair o2) {
return Float.compare(o2.value, o1.value);
}
});
//extract the indices
int[] result = new int[num];
for (int i = 0; i < num; i++) {
result[i] = pairs[i].index;
}
return result;
}
private class IndexValuePair {
private int index;
private float value;
public IndexValuePair(int index, float value) {
this.index = index;
this.value = value;
}
}
Sorting is an option, at the expense of extra memory. Consider the following algorithm.
1. Allocate additional array and copy into - O(n)
2. Sort additional array - O(n lg n)
3. Lop off the top k elements (in this case 5) - O(n), since k could be up to n
4. Iterate over the original array - O(n)
4.a search the top k elements for to see if they contain the current element - O(lg n)
So it step 4 is (n * lg n), just like the sort. The entire algorithm is n lg n, and is very simple to code.
Here's a quick and dirty example. There may be bugs in it, and obviously null checking and the like come into play.
import java.util.Arrays;
class ArrayTest {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int[] indexes = indexesOfTopElements(arr,3);
for(int i = 0; i < indexes.length; i++) {
int index = indexes[i];
System.out.println(index + " " + arr[index]);
}
}
static int[] indexesOfTopElements(int[] orig, int nummax) {
int[] copy = Arrays.copyOf(orig,orig.length);
Arrays.sort(copy);
int[] honey = Arrays.copyOfRange(copy,copy.length - nummax, copy.length);
int[] result = new int[nummax];
int resultPos = 0;
for(int i = 0; i < orig.length; i++) {
int onTrial = orig[i];
int index = Arrays.binarySearch(honey,onTrial);
if(index < 0) continue;
result[resultPos++] = i;
}
return result;
}
}
There are other things you can do to reduce the overhead of this operation. For example instead of sorting, you could opt to use a queue that just tracks the largest 5. Being ints they values would probably have to be boxed to be added to a collection (unless you rolled your own) which adds to overhead significantly.
a bit late in answering, you could also use this function that I wrote:
/**
* Return the indexes correspond to the top-k largest in an array.
*/
public static int[] maxKIndex(double[] array, int top_k) {
double[] max = new double[top_k];
int[] maxIndex = new int[top_k];
Arrays.fill(max, Double.NEGATIVE_INFINITY);
Arrays.fill(maxIndex, -1);
top: for(int i = 0; i < array.length; i++) {
for(int j = 0; j < top_k; j++) {
if(array[i] > max[j]) {
for(int x = top_k - 1; x > j; x--) {
maxIndex[x] = maxIndex[x-1]; max[x] = max[x-1];
}
maxIndex[j] = i; max[j] = array[i];
continue top;
}
}
}
return maxIndex;
}
My quick and a bit "think outside the box" idea would be to use the EvictingQueue that holds an maximum of 5 elements. You'd had to pre-fill it with the first five elements from your array (do it in a ascending order, so the first element you add is the lowest from the five).
Than you have to iterate through the array and add a new element to the queue whenever the current value is greater than the lowest value in the queue. To remember the indexes, create a wrapper object (a value/index pair).
After iterating through the whole array, you have your five maximum value/index pairs in the queue (in descending order).
It's a O(n) solution.
Arrays.sort(myArray), then take the final 5 elements.
Sort a copy if you want to preserve the original order.
If you want the indices, there isn't a quick-and-dirty solution as there would be in python or some other languages. You sort and scan, but that's ugly.
Or you could go objecty - this is java, after all.
Make an ArrayMaxFilter object. It'll have a private class ArrayElement, which consists of an index and a value and has a natural ordering by value. It'll have a method which takes a pair of ints, index and value, creates an ArrayElement of them, and drops them into a priority queue of length 5. (or however many you want to find). Submit each index/value pair from the array, then report out the values remaining in the queue.
(yes, a priority queue traditionally keeps the lowest values, but you can flip this in your implementation)
Here is my solution. Create a class that pairs an indice with a value:
public class IndiceValuePair{
private int indice;
private int value;
public IndiceValuePair(int ind, int val){
indice = ind;
value = val;
}
public int getIndice(){
return indice;
}
public int getValue(){
return value;
}
}
and then use this class in your main method:
public static void main(String[] args){
Random rand = new Random();
int[] myArray = new int[10];
IndiceValuePair[] pairs = new IndiceValuePair[5];
System.out.println("Here are the indices and their values:");
for(int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt(100);
System.out.println(i+ ": " + myArray[i]);
for(int j = 0; j < pairs.length; j++){
//for the first five entries
if(pairs[j] == null){
pairs[j] = new IndiceValuePair(i, myArray[i]);
break;
}
else if(pairs[j].getValue() < myArray[i]){
//inserts the new pair into its correct spot
for(int k = 4; k > j; k--){
pairs[k] = pairs [k-1];
}
pairs[j] = new IndiceValuePair(i, myArray[i]);
break;
}
}
}
System.out.println("\n5 Max indices and their values");
for(int i = 0; i < pairs.length; i++){
System.out.println(pairs[i].getIndice() + ": " + pairs[i].getValue());
}
}
and example output from a run:
Here are the indices and their values:
0: 13
1: 71
2: 45
3: 38
4: 43
5: 9
6: 4
7: 5
8: 59
9: 60
5 Max indices and their values
1: 71
9: 60
8: 59
2: 45
4: 43
The example I provided only generates ten ints with a value between 0 and 99 just so that I could see that it worked. You can easily change this to fit 1000 values of any size. Also, rather than run 3 separate for loops, I checked to see if the newest value I add is a max value right after I add to to myArray. Give it a run and see if it works for you
CodingBat > Java > Array-1 > reverse3:
Given an array of ints length 3, return a new array with the elements in reverse order, so {1, 2, 3} becomes {3, 2, 1}.
public int[] reverse3(int[] nums) {
int[] values = new int[3];
for (int i = 0; i <= nums.length - 1; i++) {
for (int j = nums.length-1; j >= 0; j--) {
values[i] = nums[j];
}
}
return values;
}
I can't get this to work properly, usually the last int in the array, becomes every single int in the new array
You don't want a two-level loop. Just have one loop:
for(int i = 0, j = nums.length - 1; i < nums.length; i++,j--) {
values[i] = nums[j];
}
or, alternately, just don't track j sepearately, and do this:
for(int i = 0; i < nums.length; i++) {
values[i] = nums[nums.length - 1 - i];
}
Unless this is a homework, why not just use Apache ArrayUtils'
ArrayUtils.reverse(nums)
Never re-invent the wheel :)
The length of the input int[] is fixed at 3? Then it doesn't get any simpler than this.
public int[] reverse3(int[] nums) {
return new int[] { nums[2], nums[1], nums[0] };
}
See also:
CodingBat/Java/Array-1/reverse3
Note that Array-1 is "Basic array problems -- no loops." You can use a loop if you want, but it's designed NOT to be solved using loops.
Firstly, while creating new array give it size of old array.
Next, when you're reversing an array, you don't need two loops, just one:
int length = oldArray.length
for(int i = 0; i < length; i++)
{
newArray[length-i-1] = oldArray[i]
}
You only want a single loop, but with indices going both ways:
public int[] reverse(int[] nums) {
int[] back = new int[nums.length];
int i,j;
for (i=0,j=nums.length-1 ; i<nums.length ; i++,j--)
back[i] = nums[j];
return back;
}
public int[] reverse3(int[] nums) {
int rotate[]={nums[2],nums[1],nums[0]};
return rotate;
}
This code gives correct output:-
public int[] reverse3(int[] nums) {
int[] myArray=new int[3];
myArray[0]=nums[2];
myArray[1]=nums[1];
myArray[2]=nums[0];
return myArray;
}
I got this with Python.. So you can get the idea behind it
def reverse3(nums):
num = []
for i in range(len(nums)):
num.append(nums[len(nums) - i - 1])
return num
In your code, for each value of i, you are setting target array elements at i to value in "nums" at j. That is how you end up with same value for all the elements at the end of all iterations.
First of all, very bad logic to have two loops for a simple swap algorithm such as :
public static void reverse(int[] b) {
int left = 0; // index of leftmost element
int right = b.length-1; // index of rightmost element
while (left < right) {
// exchange the left and right elements
int temp = b[left];
b[left] = b[right];
b[right] = temp;
// move the bounds toward the center
left++;
right--;
}
}//endmethod reverse
or simplified:
for (int left=0, int right=b.length-1; left<right; left++, right--) {
// exchange the first and last
int temp = b[left]; b[left] = b[right]; b[right] = temp;
}
Why go through all this pain, why dont you trust Java's built-in APIs and do something like
public static Object[] reverse(Object[] array)
{
List<Object> list = Arrays.asList(array);
Collections.reverse(list);
return list.toArray();
}
public int[] reverse3(int[] nums) {
int[] values = new int[nums.length];
for(int i=0; i<nums.length; i++) {
values[nums.length - (i + 1)]=nums[i];
}
return values;
}