This question already has answers here:
What is the difference between Linear search and Binary search?
(11 answers)
Closed 2 years ago.
Given an array of elements of length N, ranging from 0 to N – 1. All elements may not be present in the array. If element is not present then there will be -1 present in the array. Rearrange the array such that A[i] = i and if i is not present, display -1 at that place
So that is the question, but my binarySearch is not working, why?
for(int i = 0; i < size; i++) {
int res = i;
// System.out.println(Arrays.binarySearch(arr,res));
int result = Arrays.binarySearch(arr,res);
if(result == -1)
arr[i] = -1;
else {
arr[i] = i;
}
}
for(int i = 0; i < size; i++) {
System.out.print(arr[i]+" ");
}
Binary search works only with sorted arrays. Try using a different search algorithm
If you can use additional array, the solution may be as follows:
Create resulting array
Fill resulting array with -1
Iterate over input array and fill appropriate numbers in the resulting array.
// input array
int[] arr = {-1, 2, 3, 0};
// prepare new resulting array
int[] res = new int[arr.length];
// fill with -1
// Arrays.fill(res, -1); // use this shortcut if you're allowed to use library
for (int i = 0; i < res.length; i++) {
res[i] = -1;
}
// rearrange
for (int i = 0; i < arr.length; i++) {
if (arr[i] != -1) {
res[arr[i]] = arr[i];
}
}
System.out.println("input data: " + Arrays.toString(arr));
System.out.println("rearranged: " + Arrays.toString(res));
Output:
input data: [-1, 2, 3, 0]
rearranged: [0, -1, 2, 3]
Update
Recursive solution without using extra array:
public static void test() {
int[] arr = {-1, 4, 2, 0, 1, 3};
System.out.println("input data: " + Arrays.toString(arr));
// rearrange
for (int i = 0; i < arr.length; i++) {
if (arr[i] != -1 && arr[i] != i) {
swapAtIndex(arr, i);
}
}
System.out.println("rearranged: " + Arrays.toString(arr));
}
private static void swapAtIndex(int[] arr, int i) {
int t = arr[i];
if (t != -1 && t != i) {
int t2 = arr[t];
arr[t] = t;
arr[i] = t2;
if (t2 != -1) {
swapAtIndex(arr, i); // continue swapping at the same index
}
}
}
output:
input data: [-1, 4, 2, 0, 1, 3]
rearranged: [0, 1, 2, 3, 4, -1]
For the input array without -1, you'll get a sorted array after rearrangement:
input data: [5, 4, 2, 0, 1, 3]
rearranged: [0, 1, 2, 3, 4, 5]
Related
To begin, I am doing this using only arrays (no hash maps or array lists).
I am trying to create a method, project, which inputs two integer arrays with different sizes.
I am trying to compare them in a way to get the following output: projecting [1, 3, 5, 3] to [2, 1, 6, 3, 1, 4, 5, 3] results in: [1, 3, 1, 5, 3].
However, projecting [2, 1, 6, 3, 1, 4, 5, 3] to [1, 3, 5, 3] results in: [1, 3, 5, 3].
I believe the nested for loop might be wrong as it is iterating through the first indices for the first array all the way through the second array, then going to the next.
I'm getting an ArrayIndexOutOfBoundsException for the starred line (tempArray[i] == arr1[i], I know it shouldn't be tempArray[i] but not sure what exactly to put).
I'm not sure how to compare them in a way to produce the line above, as it needs to be "in order". What could be the best way to accomplish this?
I attempted the following code:
public int[] project(int[] arr1, int[] arr2) {
int counter = 0;
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
counter++;
}
}
}
int[] tempArray = new int[counter];
for(int i = 0 ; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if(arr1[i] == arr2[j]) {
tempArray[i] = arr1[i]; // UNDERLINED
}
}
}
}
Edit
The ArrayIndexOutOfBounds error is gone, but now my return statement is: projecting [1, 3, 5] to [2, 1, 6, 3, 1, 4, 5, 3] results in: [1, 3, 5, 0, 0], when it needs to be: projecting [1, 3, 5] to [2, 1, 6, 3, 1, 4, 5, 3] results in: [1, 3, 1, 5, 3].
Any idea what is causing this issue?
I think you have a typo in your first for loop
change this to later
arr1[i] == arr2[i]
to
arr1[i] == arr2[j]
Regarding overlapping issues in the projection array, you need to maintain different value as your index rather than i or j which is used by arr1 and arr2 respectively
int[] tempArray = new int[counter];
int index = 0;
for(int i=0 ; i < arr1.length; i++) {
for (int j=0; j < arr2.length; j++) {
if(arr1[i] == arr2[j]) {
tempArray[index++] = arr1[i];
}
}
}
For the values which you are expecting you should loop through arr2 first
for(int j=0 ; j < arr2.length; j++) {
for (int i=0; i < arr1.length; i++) {
if(arr1[i] == arr2[j]) {
tempArray[index++] = arr1[i];
}
}
}
If the contents of array are not hardcoded and you dont know the order in which you want to pass, you can make use of length
int[] ans;
if(a.length < b.length) {
ans = project(a, b);
} else {
ans = project(b, a);
}
Output:
[1, 3, 1, 5, 3]
You currently have index variables (i, j) tracking the indexes of each input array as you loop through them, but you also need to keep track of the write head of the result array. Initialize, say int k = 0 before the outer for loop, then set the value like this: tempArray[k++] = array1[i];.
You can forgo the first loop If you are OK with performing a single array copy. Initialize an array as long as the second input array (since there can never be more duplicated elements than existing elements) as the tempArray. Then if you want it to fit exactly, initialize the final array to the exact length k and use System#arrayCopy.
this will probably solve your problem
public int[] project(int[] arr1, int[] arr2) {
int counter = 0;
for (int i : arr2) {
if (Arrays.binarySearch(arr1, i) >= 0) {
counter++;
}
}
int[] arr4 = new int[counter];
int index = 0;
for (int i : arr2) {
if (Arrays.binarySearch(arr1, i) >= 0) {
arr4[index++] = i;
}
}
return arr4;
}
The nested iteration is expensive, so we want to avoid that. The first thing to do is sort the array we are projecting from so we can perform a binary search on it. Second, don't execute the nested iteration to determine the output array size. Create an array the size of the array we are projecting to since it can be no longer than that.
public int[] projection(int[] a, int[] b) {
int[] temp = new int[b.length];
int nextIndex = 0;
for (int x : b) {
if (contains(a, x)) {
temp[nextIndex++] = x;
}
}
return slice(temp, nextIndex);
}
private boolean contains(int[] array, int value) {
for (int element : array) {
if (element == value) {
return true;
}
}
return false;
}
private int[] slice(int[] src, int size) {
int[] slice = new int[size];
for (int index = 0 ; index < size ; ++index) {
slice[index] = src[index];
}
return slice;
}
For your second problem, I think, in your temporary array, you should be saving the values from arr2[j] instead of arr1[i].
Also, you need a different counter (set to 0 initially and incremented in the loop) for setting the values in tempArray[counter].
What I mean exactly is:
int counter = 0;
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
tempArray[counter] = arr2[j];
counter++;
}
}
}
This question already has an answer here:
How do I calculate permutation? [closed]
(1 answer)
Closed 5 years ago.
Given an array of size n, generate and print all possible permutations of r elements in array.
For example, if n is 4, input array is [0, 1, 2, 3], and r is 3, then output should be
[0, 1, 2]
[0, 1, 3]
[0, 2, 1]
[0, 2, 3]
[0, 3, 1]
[0, 3, 2]
[1, 0, 2]
[1, 0, 3]
[1, 2, 0]
[1, 2, 3]
[1, 3, 0]
[1, 3, 2]
[2, 0, 1]
[2, 0, 3]
[2, 1, 0]
[2, 1, 3]
[2, 3, 0]
[2, 3, 1]
[3, 0, 1]
[3, 0, 2]
[3, 1, 0]
[3, 1, 2]
[3, 2, 0]
[3, 2, 1]
All elements in the input array are integers, from 0 to n-1. How can I use Java to print all possible permutations?
Important: the number of all elements in a single permutation is not always the size of original array. It's less or equal to the size of original array. Additionally, the order of elements in each permutation does matter.
I have written some code when n=4 and r=3. If n = 100 and r = 50, my code will be really ugly. Is there any smart way to do this when parameters are only n and r?
public static void main(String[] args) {
// original array
ArrayList < Integer > items = new ArrayList < > ();
// all permutations
ArrayList < ArrayList < Integer >> allPermutations = new ArrayList < ArrayList < Integer >> ();
// define the end item of the original array.
// this is n, suppose it's 4 now.
int endItem = 4;
for (int i = 0; i < endItem; i++) {
items.add(i);
}
// r means how many elements in each single permutation
// suppose it's 3 now, i have to write for-loop three times
// if r is 100, i have to write for-loop 100 times
// first of the "r"
for (int i = 0; i < items.size(); i++) {
// second of the "r"
for (int j = 0; j < items.size(); j++) {
// can't be identical to i
if (j == i)
continue;
// third of the "r"
for (int k = 0; k < items.size(); k++) {
// can't be identical to i or j
if (k == i || k == j)
continue;
// a single permutation
ArrayList < Integer > singlePermutation = new ArrayList < > ();
singlePermutation.add(items.get(i));
singlePermutation.add(items.get(j));
singlePermutation.add(items.get(k));
// all permutations
allPermutations.add(singlePermutation);
}
}
}
for (ArrayList < Integer > permutation: allPermutations) {
System.out.println(permutation);
}
System.out.println(allPermutations.size());
}
Moved solution from question to answer:
Solution:
Thanks to older coder, I managed to find the solution.
public class PermutationTest10 {
// a is the original array
// k is the number of elements in each permutation
public static ArrayList<ArrayList<Integer>> choose(ArrayList<Integer> a, int k) {
ArrayList<ArrayList<Integer>> allPermutations = new ArrayList<ArrayList<Integer>>();
enumerate(a, a.size(), k, allPermutations);
return allPermutations;
}
// a is the original array
// n is the array size
// k is the number of elements in each permutation
// allPermutations is all different permutations
private static void enumerate(ArrayList<Integer> a, int n, int k, ArrayList<ArrayList<Integer>> allPermutations) {
if (k == 0) {
ArrayList<Integer> singlePermutation = new ArrayList<Integer>();
for (int i = n; i < a.size(); i++){
singlePermutation.add(a.get(i));
}
allPermutations.add(singlePermutation);
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, n-1);
enumerate(a, n-1, k-1, allPermutations);
swap(a, i, n-1);
}
}
// helper function that swaps a.get(i) and a.get(j)
public static void swap(ArrayList<Integer> a, int i, int j) {
Integer temp = a.get(i);
a.set(i, a.get(j));
a.set(j, temp);
}
// sample client
public static void main(String[] args) {
// n is the end item of the array.
// if n = 5, the array is [0, 1, 2, 3, 4, 5]
// k is the number of elements of each permutation.
int n =5;
int k =3;
// create original array
ArrayList<Integer> elements = new ArrayList<> ();
for (int i =0; i < n; i ++){
elements.add(i);
}
ArrayList<Integer> a = new ArrayList<> ();
for (int i = 0; i < n; i ++){
a.add(elements.get(i));
}
System.out.println(choose(a, k));
}
}
I need some help, guys.
Here is the assignment: Create a program to remove all the duplicates from a random array of integers. For example, if the array has the values
4, 7, 10, 4, 9, 5, 10, 7, 3, 5
then the array should be changed to
4, 7, 10, 9, 5, 3
The program should consist of two classes DeleteDuplicate and DeleteDuplicateDemo.
The DeleteDuplicate class should do the following
1. Have a method that checks for duplicate values.
2. Keep track of currentsize of array
3. Have a method that Delete duplicates (replace duplicate values with the next value in the array.)
The DeleteDuplicateDemo class should do the following
1. Have your main method.
2. Create a random array with a length of 10 numbers ranging from 1-10.
3. Display original random array.
4. Call(s) to DeleteDuplicate methods to find and remove duplicates.
5. Display new array without duplicates.
Sample Output:
[8, 5, 7, 3, 2, 5, 6, 3, 6, 7]
[8, 5, 7, 3, 2, 6]
Here is the code for DeleteDuplicateDemo:
import java.util.*;
public class DeleteDuplicateDemo
{
public static void main(String[] args)
{
Random random = new Random();
int array[]= new int[10];
for (int i = 0; i < array.length; i++)
{
array[i] = random.nextInt(10)+ 1;
}
for (int i = 0; i < array.length; i++)
{
System.out.print(array[i] + " ");
}
System.out.println();
DeleteDuplicate class1 = new DeleteDuplicate();
array = class1.removeDuplicates(array);
for (int i = 0; i < array.length; i++)
{
System.out.print(array[i] + " ");
}
}
}
Here is the code for DeleteDuplicate:
import java.util.Arrays;
public class DeleteDuplicate
{
private static int[] remove(int[] array)
{
int current = array[0];
boolean found = false;
for (int i = 0; i < array.length; i++)
{
if (current == array[i] && !found)
{
found = true;
}
else if (current != array[i])
{
System.out.print(" " + current);
current = array[i];
found = false;
}
}
System.out.print(" " + current);
return array;
}
public static int[] removeDuplicates(int[] array) {
// Sorting array to bring duplicates together
Arrays.sort(array);
int[] finalArray = new int[array.length];
int previous = array[0];
finalArray[0] = previous;
for (int i = 1; i < array.length; i++){
int value = array[i];
if (previous != value){
finalArray[i] = value;
}
previous = value;
}
return finalArray;
}
}
How can I make it work? I only have a problem with calling another class. Thank you!
In your DeleteDuplicateDemo class, change
DeleteDuplicate class1 = new DeleteDuplicate();
array = class1.removeDuplicates(array);
to
array = DeleteDuplicate.removeDuplicates(array);
In your DeleteDuplicate class, change
for (int i = 1; i < array.length; i++){
int value = array[i];
if (previous != value){
finalArray[i] = value;
}
previous = value;
}
to
for (int i = 1, j = 0; i < array.length; i++){
int value = array[i];
if (previous != value){
finalArray[j] = value;
j++;
}
previous = value;
}
Then when you are printing out the values of array to the console the 2nd time, make sure to do a check for if array[i] != null before printing array[i].
Try this.
public static int[] removeDuplicates(int[] array) {
return IntStream.of(array).distinct().toArray();
}
test:
int[] array = {8, 5, 7, 3, 2, 5, 6, 3, 6, 7};
System.out.println(Arrays.toString(removeDuplicates(array)));
// -> [8, 5, 7, 3, 2, 6]
The removal code is too complex: rather than making a separate method for removing the item, walk through the array starting at index 1, and copy from the reading index into the writing index if the data that you write is different from the item at index i-1:
int rdIndex = 1;
int wrIndex = 1;
while (rdIndex != array.length) {
if (array[wrIndex-1] != array[rdIndex]) {
array[wrIndex++] = array[rdIndex];
}
rdIndex++;
}
return Arrays.copyOf(array, wrIndex);
At the end of the loop wrIndex indicates the number of items to be copied into the result array.
Demo.
I keep getting an out of bounds error whenever i try to run my code. Does anyone know what is wrong with it? I can't seem to figure it out.
public class Swapper{
/**
This method swaps the first and second half of the given array.
#param values an array
*/
public void swapFirstAndSecondHalf(int[] values) {
// your work here
int[] first = new int[values.length/2];
int[] second = new int[values.length/2];
for(int i = 0; i < values.length / 2; i++) {
second[i] = values[i];
}
for (int j = values.length / 2; j < values.length; j++) {
first[j] = values[j];
}
for(int k = 0; k < values.length / 2; k++) {
values[k] = first[k];
}
for(int l = values.length / 2; l < values.length; l++) {
values[l] = second[l];
}
}
// This method is used to check your work
public int[] check(int[] values) {
swapFirstAndSecondHalf(values);
return values;
}
}
int[] first = new int[values.length/2];
So indexes [0..values.length/2 - 1] are valid for first.
for (int j=values.length/2; j<values.length; j++)
{
first[j] = values[j];
}
So with the first value of j being values.length/2, it's already out of bounds.
You need to practice debugging, placing a break point and tracing the code as it executes.
You could have used System.arraycopy() instead of all the for looping.
public static void main(String[] args) throws Exception {
int[] values = {1, 2, 3, 4, 5};
values = swapFirstAndSecondHalf(values);
System.out.println(Arrays.toString(values));
values = new int[]{1, 2, 3, 4, 5, 6};
values = swapFirstAndSecondHalf(values);
System.out.println(Arrays.toString(values));
}
public static int[] swapFirstAndSecondHalf(int[] values) {
boolean evenSize = values.length % 2 == 0;
int half = values.length / 2;
int[] swapper = new int[values.length];
System.arraycopy(values, evenSize ? half : half + 1, swapper, 0, half);
System.arraycopy(values, 0, swapper, evenSize ? half : half + 1, half);
// The middle number stays the middle number
if (!evenSize) {
swapper[half] = values[half];
}
return swapper;
}
Results:
[4, 5, 3, 1, 2]
[4, 5, 6, 1, 2, 3]
If you're wanting the middle number, for an odd sized array, to be part of the second half then the swapFirstAndSecondHalf() would look like this:
public static int[] swapFirstAndSecondHalf(int[] values) {
boolean evenSize = values.length % 2 == 0;
int half = values.length / 2;
int[] swapper = new int[values.length];
System.arraycopy(values, half, swapper, 0, evenSize ? half : half + 1);
System.arraycopy(values, 0, swapper, evenSize ? half : half + 1, half);
return swapper;
}
Results:
[4, 5, 3, 1, 2]
[4, 5, 6, 1, 2, 3]
Allocating new arrays is a waste of space. Just swap the halves in-place:
public static void swapFirstAndSecondHalf(int[] values) {
final int len = values.length / 2;
final int offset = values.length - len;
for (int i = 0; i < len; i++) {
int temp = values[i];
values[i] = values[offset + i];
values[offset + i] = temp;
}
}
The code allows odd length, and will leave center value alone.
I have an array, say
int a[]={2,0,1,0,1,1,0,2,1,1,1,0,1,0,1};
I need to append each of the 5 neighboring elements and assign them to a new array b with length=(a.length/5); and i want to append the 5 neighboring elements so that I have:
int b[]={20101,10211,10101}; I need to do this for various length arrays, in most cases with length of a being greater than 15.
Any help would be greatly appreciated, I'm programming in Java.
Thanks in advance.
It's pretty straighforward:
// Assuming a.length % 5 == 0.
int[] b = new int[a.length / 5];
for (int i = 0; i < a.length; i += 5) {
b[i/5] = a[i]*10000 + a[i+1]*1000 + a[i+2]*100 + a[i+3]*10 + a[i+4];
}
This sounds like a homework question, so I won't give you the complete solution, but the basic rundown is:
Compute the length of b: len = a.length / 5
Construct b with that many elements.
Initialize an index variable to point to the first element in a
For each element in b:
Construct the value for that element from a[idx]...a[idx+4]
Advance the index into a by 5.
Also note that you may need to verify that the input a is actually a multiple of 5 in length.
This works with (a.length % 5) != 0, and keeps leading zeroes (by storing digits into String).
int a[]={2,0,1,0,1,1,0,2,1,1,1,0,1,0,1,0,0,7};
final int N = 5;
String b[] = new String[(a.length + N - 1)/ N];
StringBuilder sb = new StringBuilder(N);
int x = 0;
for (int i = 0; i < b.length; i++) {
sb.setLength(0);
for (int k = 0; k < N && x < a.length; k++) {
sb.append(a[x++]);
}
b[i] = sb.toString();
}
System.out.println(java.util.Arrays.toString(b));
// prints "[20101, 10211, 10101, 007]"
Alternately, you can also use regex:
String[] arr =
java.util.Arrays.toString(a)
.replaceAll("\\D", "")
.split("(?<=\\G.{5})");
System.out.println(java.util.Arrays.toString(arr));
// prints "[20101, 10211, 10101, 007]"
Basically this uses Arrays.toString(int[]) to append all digits into one long String, then removes all non-digits \D, then uses \G-anchored lookbehind to split every .{5}
Naive approach.
import java.util.ArrayList;
/* Naive approach */
public class j2728476 {
public static void main(String[] args) {
int a[] = {2,0,1,0,1,1,0,2,1,1,1,0,1,0,1};
ArrayList<String> al = new ArrayList<String>();
String s = "";
for (int i = 0; i < a.length; i++) {
if (i % 5 == 0 && i != 0) {
al.add(s);
s = "" + a[i];
} else {
s += a[i];
}
}
al.add(s);
for (String t : al) {
// convert values to ints ...
System.out.println(t);
}
}
}
Will print:
20101
10211
10101
import java.util.Arrays;
public class MainClass {
public static void main(String args[]) throws Exception {
int array[] = { 2, 5, -2, 6, -3, 8, 0, -7, -9, 4 };
Arrays.sort(array);
printArray("Sorted array", array);
int index = Arrays.binarySearch(array, 1);
System.out.println("Didn't find 1 # "
+ index);
int newIndex = -index - 1;
array = insertElement(array, 1, newIndex);
printArray("With 1 added", array);
}
private static void printArray(String message, int array[]) {
System.out.println(message
+ ": [length: " + array.length + "]");
for (int i = 0; i < array.length; i++) {
if (i != 0){
System.out.print(", ");
}
System.out.print(array[i]);
}
System.out.println();
}
private static int[] insertElement(int original[],
int element, int index) {
int length = original.length;
int destination[] = new int[length + 1];
System.arraycopy(original, 0, destination, 0, index);
destination[index] = element;
System.arraycopy(original, index, destination, index
+ 1, length - index);
return destination;
}
}
It will print
Sorted array: [length: 10]
-9, -7, -3, -2, 0, 2, 4, 5, 6, 8
Didn't find 1 # -6
With 1 added: [length: 11]
-9, -7, -3, -2, 0, 1, 2, 4, 5, 6, 8