I have written the following code that takes two arrays and searches the index of the first occurrence of each value from the first array in the second one. For example if first = {15, 10, 18, 17, 15} and second = {10, 15, 10, 17} then the output would be an array with an equal length to first which contains the indices output = {1, 0, -1, 3, 1}, as e.g. 15 occurs in index 1 of the second array, 10 occurs at the 0th index, etc. The index will be -1 if the value in first doesn't occur in second. The code I've written to loop through the arrays is as follows:
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
int index = -1;
for (int i = 0; i < first.length; i ++) {
for (int j = 0; j < second.length; j ++) {
if (first[i] == second[j])
index = j;
}
indices[i] = index;
}
return indices;
}
However, for the given example the output is instead {1, 2, 2, 3, 1}. I think I do understand the issue; since 10 occurs twice in second then the index of the second occurrence is recorded, but I don't know how to get around this. Putting a break; statement after the if clause doesn't seem to fix it.
This would be straightforward by using the ArrayUtils.indexOf() utility method. Moving through the second array, call ArrayUtils.indexOf() for each of its elements in reference to the first array, storing the results in the indices array. This will also mean that there would be a single loop, not a nested loop.
The ArrayUtils class is a part of the org.apache.commons.lang3 library.
A different option, not requiring an external library, would be to convert your arrays to Lists and then take advantage of the List.indexOf() method.
I hope that helps!
Two issues in your code:
Once index is set to any value at all, it can never again become -1
Once you find the first occurrence in the second array, you keep going - need a break.
Updated code:
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
int index;
for (int i = 0; i < first.length; i ++) {
// reset index on each iteration
index = -1;
for (int j = 0; j < second.length; j ++) {
if (first[i] == second[j]) {
// once the first match is found, break out of the inner loop
index = j;
break;
}
}
indices[i] = index;
}
return indices;
}
try this
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
//fill all values with -1
Arrays.fill(indices,0,first.length - 1, -1);
for (int i = 0; i < first.length; i++) {
for (int j = 0; j < second.length; j++) {
// when you met with same value fill your indices array with second array's value's index and break the loop
if (first[i] == second[j]) {
indices[i] = j;
break;
}
}
}
return indices;
}
Just add break after found the element and reset the index
public static int[] searchIndexes(int[] first, int[] second) {
int[] indices = new int[first.length];
int index = -1;
for (int i = 0; i < first.length; i++) {
index = -1;
for (int j = 0; j < second.length; j++) {
if (first[i] == second[j]) {
index = j;
break;
}
}
indices[i] = index;
}
return indices;
}
, main
public static void main(String args[]) {
int[] indices = searchIndexes(new int[] { 15, 10, 18, 17, 15 }, new int[] { 10, 15, 10, 17 });
for (int i = 0; i < indices.length; i++)
System.out.print(indices[i] + " ");
System.out.println();
}
, output
1 0 -1 3 1
Related
There is a fixed length array arr of integers, duplicate each occurrence of zero, shifting the remaining elements to the right. The elements beyond the length of the original array are not written.
We have to modify input array in place and doesn't have to create new array.
So I created that but it is duplicating the zero which is at the end of array and not the previous zeros. Can somebody help me with this?
public static void addPos() {
int arr[] = { 1, 2, 0, 3, 0, 5, 0, 7, 8 };
int result[] = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
int loc = i;
for (int j = 0; j < loc; j++) {
result[j] = arr[j];
result[loc] = 0;
}
for (int j = loc + 1; j < arr.length; j++) {
result[j] = arr[j - 1];
}
}
}
for (int k = 0; k < arr.length; k++)
System.out.println(result[k]);
}
Output
1
2
0
3
0
5
0
0
7
Expected output:
1
2
0
0
3
0
0
5
0
Every iteration of the loop overwrites the results from the previous iteration, so the end result only shows the results from the last iteration, which duplicates the last 0 is duplicated.
One way to solve this is by iterating backwards "right to left". It simplifies a lot of things. You can get rid of the auxiliary result array. The basic idea is, go backwards in the array, and every time you find a 0, you duplicate it by rewriting the array to the right of the zero.
public static void addPos() {
int arr[] = {1, 2, 0, 3, 0, 5, 0, 7, 8};
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] == 0) {
// duplicate it!
for (int j = arr.length - 1; j > i; j--) {
arr[j] = arr[j-1];
}
}
}
for (int k = 0; k < arr.length; k++) {
System.out.println(arr[k]);
}
}
The for loop keeps overwriting the values in result array, hence the result shows only last duplication.You should not be using the result array at all.Keep shipting values in the original array itself.
You can refer to below code.
for(int i=0;i<arr.length-1;i++){
if(arr[i]==0){
for(int j=arr.length-1;j>i;j--){
arr[j]=arr[j-1];
}
i++;
}
}
public void duplicateZeros(int[] arr)
{
int i=0;
while(i<arr.length)
{
if(arr[i]==0)
{
int j=arr.length-1;
while(j != i)
{
arr[j]=arr[j-1];
j--;
}
i=i+2;
}
else
{
i=i+1;
}
}
}
Without using any other Array.
class Solution {
public void duplicateZeros(int[] arr) {
for(int i=0;i<arr.length;i++){
if(arr[i]==0){
for(int j=arr.length-1;j>i;j--){
arr[j]=arr[j-1];
}
i=i+1;
}
}
}
}
So one has this:
int[] arr = { 1, 2, 0, 3, 0, 5, 0, 7, 8 };
public static void duplicateZeros(int[] arr) {
and should get
{ 1, 2, 0, 3, 0, 5, 0, 7, 8 }
v___
{ 1, 2, 0, 0, 3, 0, 5, 0, 7 }
v___
{ 1, 2, 0, 0, 3, 0, 0, 5, 0 }
This looks like:
for (int i = 1; i < n; ++i) {
if (arr[i - 1] == 0) {
insert at i a 0;
}
}
insert at i a 0:
// First move the remaining to the right: i .. n-2
...
// Then fill in the zero
arr[i] = 0;
Python solution for anyone interested adapted from here
the solution is non-trivial if you do not separate the action of the pointer iterating over the list and the insertions. It's very easy to write a for-loop that adds 0's ad-infinitum.
def duplicateZeros(arr):
# define the incrementor
i = 0
# loop through all dynamic elements
while i < len(arr)-1:
# if the character is a zero
if arr[i]==0:
# remove the last item from the array
arr.pop()
# insert a zero in front of current element
arr.insert(i+1, 0)
# move one place forward
i += 1
# increment to the next character
i += 1
Solution 1: Loop from start to end. If zero is found, move the elements from next index and fill the next as zero and skip next.
public static void duplicateZeros(int[] arr) {
System.out.println("BEGIN duplicateZeros:" + Arrays.toString(arr));
for(int i=0; i<arr.length-1; ++i) {
if (arr[i] == 0) {
move(arr, i);
++i;
}
}
System.out.println("END duplicateZeros:" + Arrays.toString(arr) +"\n");
}
private static void move(int[] arr, int index) {
// move to the right from index+1
for(int i=arr.length-1; i>index; i--) {
arr[i] = arr[i-1];
}
// fill 0 at index
arr[index] = 0 ;
}
Solution2: Loop from end to start. If zero is found, move the elements from next index and fill the current index as zero.
public static void duplicateZeros(int[] arr) {
System.out.println("BEGIN duplicateZeros:" + Arrays.toString(arr));
for(int i=arr.length-1; i>=0; i--) {
if (arr[i] == 0) {
move(arr, i);
}
}
System.out.println("END duplicateZeros:" + Arrays.toString(arr) +"\n");
}
private static void move(int[] arr, int index) {
// move to the right from index+1
for(int i=arr.length-1; i>index; i--) {
arr[i] = arr[i-1];
}
// fill 0 at index
arr[index] = 0 ;
}
class Solution:
def duplicateZeros(self, arr: List[int]) -> None:
"""
Do not return anything, modify arr in-place instead.
"""
if len(arr)==0:
return arr
index = 0
while index < len(arr):
print(index,end=" ")
if arr[index]==0:
arr.insert(index+1,0)
arr.pop()
index+=1
index+=1
Say I have an array of:
int [] I = { 1, 3, 6, 3, 7,3, 9, 3};
int value = 3;
I have a for loop that tracks the amount of occurences of the value:
int counter = 0;
for(int x = 0; x < I.length; x++)
{
if(I[x] == value)
{
counter++;
}
}
I make a new array with length equal to the number of occurrences, that can store all the indices of the occurences from the original array:
int [] index = new int [counter];
for(int x = 0; x < index.length; x++)
{
for(int i = 0; i<I.length; i++)
{
if(I[i] == value){
index[x] = i;
}
}
}
However, when I print my array of indices, i just get the last index printed the amount of times counter is equal to, when I want all the indices.
for(int i = 0; i<index.length; i++)
{
System.out.println(index[i]);
}
It just prints "7" (the last index) 3 times. How do I go about fixing this so I have an array of all indices?
Thank you.
Your second for loop should not be nested; you should only increment x when you find a match. Something like,
for (int i = 0, x = 0; i < I.length; i++) {
if (I[i] == value) {
index[x] = i;
x++;
}
}
Assuming you're using Java 8+, you could have written a filter() on the range of indices in the array. Like,
int[] index = IntStream.range(0, I.length).filter(i -> I[i] == value).toArray();
System.out.println(Arrays.toString(index));
Just remove the outer for loop and store into the index array as you iterate through the original array I. The problem with your code is that, since you repeat the iterations once for each index in the index array, you end up with the last found index (7 in your case).
for(int i = 0, x = 0; i < I.length; i++) {
if(I[i] == value) {
index[x++] = i;
}
}
I'm working on a problem on leetcode (Two Sum):
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 tried my own solution and the array always showed [0,0]. So I tried a solution that they had after several tweeks and that still showed [0,0] when I put it in and it was the highest ranked solution. Is it me or is it leetcode?
Original Solution:
import java.util.Arrays;
public class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
for(int i = 0; i < nums.length-1; i++)
{
for(int j = i+1; j < nums.length-1; j++)
{
if(target == (nums[i] + nums[j]))
{
indices[0] = i+1;
indices[1] = j+1;
}
}
}
return indices;
}
}
Leetcode Solution:
public class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0; i < nums.length-1; i++)
{
if(map.containsKey(target - nums[i]))
{
indices[1] = i + 1;
indices[0] = map.get(target - nums[i]);
return indices;
}
map.put(nums[i], i + 1);
}
return indices;
}
}
I don't understand why neither of these will register ints in the indices array, it continually returns [0,0] for both solutions.
In my understanding your innerloop must not start with i+1, cause you have to check each index in your array. only if the index of the inner and outer loop match, you should skip it, cause you won't add the index with itself.
you must loop your array to the end (so i removed the -1 in the for-statement)
why are you returning i+1 and j+1 if you found a match? (so i removed this)
see my code. maybe it will be more clear, what im trying to say :-)
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
int[] result = solution.twoSum(new int[] { 2, 7, 11, 15 }, 17);
System.out.println(result[0] + "/" + result[1]);
}
public int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length; j++) {
if (i == j) {
//do not use the same index for sum
continue;
}
if (target == (nums[i] + nums[j])) {
indices[0] = i;
indices[1] = j;
}
}
}
return indices;
}
}
The simplest way to loop through combinations of two within an array can be done as follows:
for(int i=0 ; i<nums.length-1 ; i++)
for(int j=i+1 ; j<nums.length ; j++)
if(nums[i]+nums[j]==target)
return new int[] {i, j};
return null; //in case there's no such case
Ok, so I have this problem where when given an Array arr, return an Array which contains only odd integers in the original order from arr.
My code:
public int [] youMakeMeOdd(int [] arr)
{
int[] odds;
odds = new int[arr.length];
for(int i = 0; i < arr.length; i++)
{
if(arr[i] % 2 != 0)
{
odds[i] = arr[i];
}
}
return odds;
}
Few Testers:
Expected...........................................................Run:
youMakeMeOdd({1,2,3}) → {1, 3}.....................{1, 0, 3}
youMakeMeOdd({2,1,3,5,7}) → {1, 3, 5, 7}.......{0, 1, 3, 5, 7}
youMakeMeOdd({2,4,6,8}) → {}........................{0, 0, 0, 0}
.
I can't seem to figure out how to put a blank space there instead of 0's. Help appreciated, thanks :)
The output array is being initialized to the size of the input array. I guess this being java code, the array elements are initialized to zero by default. So whenever the if condition does skips the ith position the default value (zero) is being shown.
public int[] youMakeMeOdd(int [] arr) {
List<Integer> odds = new ArrayList<Integer>();
for(int i = 0; i < arr.length; i++)
{
if(arr[i] % 2 != 0)
{
odds.add(arr[i]);
}
}
return convertIntegers(odds);
}
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
Iterator<Integer> iterator = integers.iterator();
for (int i = 0; i < ret.length; i++)
{
ret[i] = iterator.next().intValue();
}
return ret;
}
You could have a pre-computation loop where you just increment a counter and then allocate odds:
int counter = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 != 0)
{
counter ++;
}
}
odds = new int[counter];
I would use an ArrayList. Your problems seems to be the fact that arrays are immutable, so you it automatically fills your array with a bunch of unneeded 0s. ArrayLists can change dimensions, so you don't have to have the 0s.
You can have a look at them here: http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
Make sure you import the util package.
import java.util.*;
public ArrayList<Integer> youMakeMeOdd(int [] arr)
{
You need to specify the type that you want to hold in the angle braces. Because int is a primitive, you need to use the Integer class
ArrayList<Integer> odds;
odds = new ArrayList<>();
for(int i = 0; i < arr.length; i++)
{
if(arr[i] % 2 != 0)
{
The add method adds an integer to the end
odds.add(new Integer(arr[i]));
}
}
return odds;
}
var result = input.Select(a=>a % 2 != 0 ? a : 0).ToArray()
You can use linq easily, basically you use the original array and then use the Select to select either the value itself of the array or 0 if it's even, and then convert to an array using ToArray method.
I am trying to flatten this array:
int[][] arr = { {1, 2, 3},
{4, 5},
{6},
null,
{},
{7,8}};
I can see that in the first couple of steps it fills out the new array, but then I get the out of bounds exception error. I don't understand where my mistake is.
public static int[] concAr (int[][] arr) {
int countels=0;
for (int r = 0; r < arr.length; r++) {
if (arr[r] == null|| arr[r].length==0)
continue;
for (int c = 0; c < arr[r].length; c++) {
countels++;
}
}
int[] flatAr = new int[countels];
for(int i = 0; i < countels; i ++) {
if(arr[i]!=null) {
for(int j = 0; j < arr[i].length; j ++) {
flatAr[(i * arr.length) + j] = arr[i][j];
}
}
}
return flatAr;
}
The following indexing is wrong, because array lengths are different
flatAr[(i * arr.length) + j] = arr[i][j];
Use this after setting count to zero:
flatAr[count++] = arr[i][j];
countels is the length of the flattened array, in this case, 8. However, in your second outer loop, you index through the original, unflattened array up to countels, even though your unflattened array only has 6 elements. Once you get past those 6, you get the out of bounds exception.
The second time through, you still need to iterate the way you did the first time, and increment the index of the flattened array within the second set of loops.