I am trying to solve this LeetCode question - https://leetcode.com/problems/create-target-array-in-the-given-order/description/ where the instructions contains -
Given two arrays of integers nums and index. Your task is to create target array under the following rules:
Initially target array is empty.
From left to right read nums[i] and index[i], insert at index index[i] the value nums[i] in target array.
Repeat the previous step until there are no elements to read in nums and index.
Return the target array.
It is guaranteed that the insertion operations will be valid.
I tried out this approach but it is not working as expected.
public class LeetCode1389 {
public static void main(String[] args) {
System.out.println(Arrays.toString(createTargetArray(new int[]{0,1,2,3,4}, new int[]{0,1,2,2,1})));
}
static int[] createTargetArray(int[] nums, int[] index) {
int[] target = new int[nums.length];
for (int i = 0; i < nums.length; i++){
for (int j = 0; j < index.length; j++){
target[index[i]] = nums[i];
}
}
return target;
}
}
Use a List instead, which provides an add method to insert at a specific index. Convert the List to an int array at the end.
static int[] createTargetArray(int[] nums, int[] index) {
List<Integer> target = new ArrayList<>(nums.length);
for (int i = 0; i < nums.length; i++) target.add(index[i], nums[i]);
return target.stream().mapToInt(i -> i).toArray();
}
Related
I'm learning how to use arrays, and I'm trying to manually sort an array of integers using two ArrayList<Integer>.
Here's what I have currently:
public Object[] arraySort (int[] importedArray) {
// !!! This method returns the original imported method (?). !!!
ArrayList<Integer> unsorted = new ArrayList<>();
ArrayList<Integer> sorted = new ArrayList<>();
// Convert importedArray into unsorted Integer ArrayList
for (int i = 0; i < importedArray.length; i++) {
unsorted.add(importedArray[i]);
}
// Find minimum value of unsorted ArrayList, add to sorted ArrayList, and remove min value from unsorted
for (int i = 0; i < unsorted.size(); i++) {
int min = Integer.MAX_VALUE;
int index = 0;
for (int j = 0; j < unsorted.size(); j++) {
if (unsorted.get(j) < min) {
min = unsorted.get(j);
index = j;
}
}
unsorted.remove(index);
sorted.add(min);
}
return unsorted.toArray();
}
However, when I run the method, I get the same imported array back. The first for loop to convert int[] into ArrayList<Integer> apparently worked when I checked using print, so the problem is most likely in the second for loop.
I've also tried other insertion sorting methods, but I'm not sure what I am doing wrong with this type of sorting method. Did I totally screw up somewhere? Or is this method not possible? Thanks in advance for your help!
First of all, you should return the sorted array and not the unsorted one. You should also be careful when using unsorted.size() in the loop header because the programm will call that method every time an iteration has finished. But since you decrease the size inside of the loop with update.remove(index), the size does not stay the same and you just skip some values. Thus, you should save that value in a variable before starting the loop. The following code worked for me:
public Object[] arraySort(int[] importedArray) {
ArrayList<Integer> unsorted = new ArrayList<>();
ArrayList<Integer> sorted = new ArrayList<>();
for (int i = 0; i < importedArray.length; i++) {
unsorted.add(importedArray[i]);
}
int size = unsorted.size();
for (int i = 0; i < size; i++) {
int min = Integer.MAX_VALUE;
int index = 0;
for (int j = 0; j < unsorted.size(); j++) {
if (unsorted.get(j) < min) {
min = unsorted.get(j);
index = j;
}
}
unsorted.remove(index);
sorted.add(min);
}
return sorted.toArray();
}
I am working leetcode problem number 1365. Here is the problem below in italicized characters:
Given the array nums, for each nums[i] find out how many numbers in the array are smaller than it. That is, for each nums[i] you have to count the number of valid j's such that j != i and nums[j] < nums[i].
Return the answer in an array.
Example 1: Input: nums = [8,1,2,2,3] Output: [4,0,1,1,3] Explanation: For nums[0]=8 there exist four smaller numbers than it (1, 2, 2 and 3). For nums[1]=1 does not exist any smaller number than it. For nums[2]=2 there exist one smaller number than it (1). For nums[3]=2 there exist one smaller number than it (1). For nums[4]=3 there exist three smaller numbers than it (1, 2 and 2).
https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/
I am able to complete the task using brute force which gives an O(n^2) time. Is there a faster way to code this problem?
public static void main(String[] args) {
int[] nums = new int[] {8,1,2,2,3};
System.out.println(Arrays.toString(smallerNumbersThanCurrent(nums)));
}
public static int[] smallerNumbersThanCurrent(int[] nums) {
int[] result = new int[nums.length];
for (int x = 0; x < nums.length; x++) {
int ctr = 0;
for (int y = 0; y < nums.length; y++) {
if (nums[y] < nums[x]) {
ctr++;
}
result[x] = ctr;
}
}
return result;
}
A simple O(nlgn) solution with an O(n) space would be:
Copy the array into a temp array, O(n)
Sort the new array O(ngln)
Iterate over the original array
For every element, do a binary search over the sorted array and get the first index of the element.
The index would be the count you are after.
There is a slightly better O(n^2) approach, where you only compare each pair of indices once and updating the counts accordingly:
public static int[] smallerNumbersThanCurrent(int[] nums)
{
int[] result = new int[nums.length];
for (int x = 0; x < nums.length; x++)
{
for (int y = x + 1; y < nums.length; y++)
{
if (nums[y] < nums[x])
result[x]++;
else if (nums[y] > nums[x])
result[y]++;
}
}
return result;
}
However, at the cost of an additional array we can do it in O(ngln) by sorting the indices of the original array and then iterating through these sorted indices, updating the count accordingly. The only complication is in dealing with repeated numbers, e.g. the 2s in your example.
public static int[] smallerNumbersThanCurrent(int[] nums)
{
Integer[] idx = new Integer[nums.length];
for(int i=0; i<idx.length; i++) idx[i] = i;
Arrays.sort(idx, (a, b) -> (nums[a]-nums[b]));
int[] res = new int[nums.length];
for(int i=1; i<idx.length; i++)
{
if(nums[idx[i]] == nums[idx[i-1]])
res[idx[i]] = res[idx[i-1]];
else
res[idx[i]] = i;
}
return res;
}
Test:
int[] nums = new int[] {8,1,2,2,3};
System.out.println(Arrays.toString(smallerNumbersThanCurrent(nums)));
Output:
[4, 0, 1, 1, 3]
I have to create a method that takes in an array and value as arguments and returns a new array with the specified value removed.
Here's my attempt:
public static int[] remove(int[] nums,int value){
int[] after = new int[nums.length-1];
for (int i = 0; i < nums.length; i++) {
if (!(nums[i] == value)) {
after[i] = nums[i];
}
}
nums = after;
return nums;
}
The code throws
ArrayIndexOutOfBoundsException
bur I don't know why.
First you need to find how big the new array is, after you can populate the new array without the value to remove. There are better ways to do this, but this is to get you started.
public static int[] remove (int[] nums, int value)
{
int[] after;
//find out the length of the array
int count = 0;
for (int num : nums)
{
if (num != value)
{
count++;
}
}
after = new int[count];
//add all the elements except the remove value
int i = 0;
for (int num : nums)
{
if(num != value)
{
after[i] = num;
i++;
}
}
return after;
}
KISS. It's a 1-liner:
public static int[] remove(int[] nums, int value){
return IntStream.stream(nums).filter(i -> i != value).toArray();
}
Code is trying to copy values from original array to new array leaving a blank or space(value 0) in place of targeted value. The error ArrayIndexOutOfBoundsException is showing because you are initialising the after with nums.lenth-1 int[] after = new int[nums.length-1];
You can change that or swap the targeted element with the last element and copy entire array except the last.
public static int[] remove (int[] nums,int value){
int[] after = new int[nums.length-1];
for(int i = 0; i < nums.length; i++) {
if((nums[i] == value)) {
//changing the target value with the last value of nums array
nums[i]=nums[nums.length-1];
nums[nums.length-1]=value;
}
}
//Copying the entire array except the last
for(int i=0;i<nums.length-1;i++){
after[i]=nums[i];
}
return after;
}
And I am assuming that there is only one target element
Write a java program to sort a list of integers using ‘in place’ Quicksort algorithm.
Generate the list randomly every time using the java.util.Random class.
Allow the user to choose the size of the array. The program should display the result of sorting the array of that size using different pivot choices. In particular, try these 4 choices –
First element as pivot
Randomly choosing the pivot element
Choosing the median of 3 randomly chosen elements as the pivot
Median of first center and last element (book technique).
PLEASE dont give me the implementation because I would like to try on my own. I want to know what is inplace quick sort? How is it different from the regular quiksort. Is it regular quicksort. I am really confused. I would like someone to provide the pusedocode or explanation in plain english will help too.
Inplace sorting - it's when you operate on the original array, given to you from outside, as opposed to creating some new arrays and using them in any way. Inplace sorting takes O(1) space, as opposed to O(n)+ when using additional data structres
Example of inplace sort:
public static void simpleBubbleSort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 1; j < arr.length; j++) {
if (arr[j - 1] > arr[j]) {
swap(arr, j - 1, j);
}
}
}
}
As opposed to Merge sort that creates arrays along the way, and by the end combines them and returns NOT the original (given to us) array, but an array containing the result.
public static int[] mergeSort(int[] arr) {
if (arr.length < 2) return arr;
int mid = arr.length / 2;
int[] left = new int[mid];
int[] right = new int[mid + arr.length % 2];
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (i < mid) {
left[i] = arr[i];
} else {
right[j++] = arr[i];
}
}
// keeps going until there's 1 element in each array[]
return mergeReturn(mergeSort(left), mergeSort(right));
}
private static int[] mergeReturn(int[] leftArr, int[] rightArr) {
int leftPointer = 0, rightPointer = 0, combinedSize = leftArr.length + rightArr.length;
int[] merged = new int[combinedSize];
for (int i = 0; i < combinedSize; i++) {
if (leftPointer < leftArr.length && rightPointer < rightArr.length) {
if (leftArr[leftPointer] < rightArr[rightPointer]) {
merged[i] = leftArr[leftPointer++];
} else {
merged[i] = rightArr[rightPointer++];
}
} else if (leftPointer < leftArr.length) { // adding the last element
merged[i] = leftArr[leftPointer++];
} else {
merged[i] = rightArr[rightPointer++];
}
}
return merged;
}
I've tried many different variations, and I keep getting the same problem. After selectio nsort runs, the number of items outputted, does not match the size of my array. I've been running through with any array of size 10, yet the output does not contain 10 numbers. However, the output of selection sort is sorted.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Sorts {
public static Integer[] createArray(int size) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < size; i++)
list.add(i);
Collections.shuffle(list);
Integer[] array = list.toArray(new Integer[list.size()]);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
return array;
}
public static void selectionSort(Integer[] array) {
Integer min;
for (Integer i = 0; i < array.length - 1; i++) {
min = i;
for (Integer j = i + 1; j < array.length; j++) {
if (array[j].compareTo(array[min]) > 0) {
min = j;
}
}
if (min != i) {
Integer temp = array[i];
array[i] = array[min];
array[min] = temp;
System.out.print(array[i]);
}
}
}
public static void main(String args[]) {
int number = 10;
Integer[] list = createArray(number);
System.out.println("");
selectionSort(list);
}
}
Whenever you make a swap, you print out a number. But in an array of 10 elements, you'll only make 9 swaps -- the final element will already be in its correct place! To fix this, add System.out.print(array[array.length - 1]); to the end of your function.
Also, if the minimum element happens to be i, then no swap will be performed and no element printed. This still sorts the array, but if you want it to be printed out, you could remove the if (min != i) statement and simply do a swap on every pass through the list.
You should also take a look at using ints rather than Integers. An Integer is generally slower than an int and you usually only use them when Java wants an object.