Java Subarray with specific size from array - java

If I have array like [1,2,3,4] and k = 3 then output should be [1,2,3][2,3,4] which is in this order. The idea is to get subarray with k elements and then the next to start from the next element and also to have k elements
I can't think of a way to do it more generic for any value of k.
final int arr[] = new int[] { 1, 2, 3, 4 };
final int max = 2;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
for (int k = 0; k < max; k = k + 2) {
System.out.println(i + "" + j);
}
}
}

You can extract parts of an array by calling Arrays.copyOfRange() method:
int[] arr = {1, 2, 3, 4};
int k = 3;
int numberOfResults = arr.length - k + 1;
for (int i = 0; i < numberOfResults; i++) {
int[] result = Arrays.copyOfRange(arr,i,i+k);
System.out.println(Arrays.toString(result));
}

Related

Delete local maximum

A local maximum is an element that is greater than any of its neighboring elements. You must remove elements that are local maxima in the original array.
Input array:
[18, 1, 3, 6, 7, -5]
output array:
[1, 3, 6, -5]
public static int[] removeLocalMaxima(int[] array){
int[] result = new int[array.length];
int j = 0;
for (int i = 0; i < array.length - 1; i++, j++) {
if(array[i] > array[i + 1]){
result[j] = array[++i];
}else {
result[j] = array[i];
}
}
return Arrays.copyOf(result, j);
}
if you set it like that, then something is not working:
array = new int[1000];
Arrays.fill(array, 15);
array[0] = -20;
array[999] = 25;
array[168] = 18;
array[421] = 0;
actual = LocalMaximaRemove.removeLocalMaxima(array);
assertEquals(998, actual.length);
assertEquals(-20, actual[0]);
assertEquals(15, actual[997]);
assertEquals(0, actual[420]);
public static int[] removeLocalMaxima(int[] array){
int[] result = new int[array.length];
int j = 0;
for (int i = 0; i < array.length; i++) {
if ((i > 0 && array[i] <= array[i - 1])
|| (i != array.length - 1 && array[i] <= array[i + 1])){
result[j++] = array[i];
}
}
return Arrays.copyOf(result, j);
}
My function saves in result array only elements that are less or equal of any of its neightbors.

How to keep track of array elements that have already been printed and skip them (Java)

I am writing a program that keeps track of the number of non-unique elements in an array and prints them along with their frequency. The problem with my current code is that it will print the repeated numbers more than once. I just want to print the non unique number and its frequency once, but I can't figure out how to do that. Here's my current logic. Any help would be greatly appreciated.
int numNonUnique = 0;
int N = A.length;
for (int i = 0; i < N; i++)
{
int count=0;
for (int j = 0; j < N; j++)
{
if (A[i] == A[j])
count++;
}
if(count>1)
{
numNonUnique = count;
int currentNum = A[i];
System.out.println(currentNum + " -> "+ numNonUnique);
}
}
//Initialize array
int[] A = {-1, 2, 3, 1, 2, 4, 7, 8, 7, -1};
int numNonUnique = 0;
//Array frequency will store frequencies of element
int [] frequency = new int [A.length];
int visited = -1;
for(int i = 0; i < A.length; i++){
int count = 1;
for(int j = i+1; j < A.length; j++){
if(A[i] == A[j]){
count++;
//To avoid counting same element again
frequency[j] = visited;
}
}
if(frequency[i] != visited) frequency[i] = count;
}
//Displays the frequency of each element present in array
for(int i = 0; i < frequency.length; i++){
if(frequency[i] != visited && frequency[i]>1){
numNonUnique++;
System.out.println(A[i] + " -> "+ frequency[i]);
}
}
System.out.println("Non unique count : "+ numNonUnique);

How to shift elements to left after removing array element?

I was asked to write, to remove the element (lets say k=30) from the array and shift the other elements to its left without using inbuilt methods.
I have tried the below approach.
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int count = 0;
System.out.println("---Original Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k)
count++;
}
for (int j = 0; j < count; j++) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
for (int l = i; l < arr.length - 1; l++) {
arr[l] = arr[l + 1];
}
}
}
}
System.out.println("---Modified Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
I need output like this: [1 2 4 5 6 0 0]
But the output from the above logic is: [1 2 4 5 6 6 6]
Also, I'm worried about using nested for loops here. Is there any way that we can reduce the time complexity with out using any inbuilt methods?
Here is another variant:
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != k) {
arr[j++] = arr[i];
}
}
while (j < arr.length) {
arr[j++] = 0;
}
In order to not change your approach drastically, I would suggest adding another iteration of the array at the end, to insert 0s to count-many indices from the end of your array.
This would be as simple as adding the following snippet:
// nested for loop
// ...
// set trailing elements to 0s
for (int i = 0; i < count ; i++)
arr[arr.length-1-i] = 0;
System.out.println("\n---Modified Array------");
// ...
There are some cleaner/more-efficient ways of solving this problem.
Based exactly on your approach, I went ahead and made a modification to your nested loop to not require another iteration.
for (int j = 0; j < count; j++) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
for (int l = i; l < arr.length - 1; l++)
arr[l] = arr[l + 1];
// since we have performed the shifting, we can safely set the last element to 0
arr[arr.length-1] = 0; // <----- this was missing!!
}
}
}
The following code gives the desired result:
int [] arr = { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int elementCount = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
++elementCount;
}
}
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k) {
count++;
for (int j = i; j < arr.length-1; j++) {
arr[j] = arr[j+1];
}
arr[arr.length-1] = 0;
}
if (count == elementCount) {
break;
}
}
I don't know if it helps. This is a simplified aproach, that is easier to read and understand(at least for people that learned C), that does removal as required....
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int i=0;
int j=0;
for(;j<arr.length;i++,j++){
if((arr[i]=arr[j])==k) i--;
}
while(i<j)arr[i++]=0;
System.err.println(Arrays.toString(arr));
}
output:[1, 2, 4, 5, 6, 0, 0]
First version with a small fix on your code. You issue is that the shifted elements need to be replaced by zero. Which require basically an if statement with the arr.length - count
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int count = 0;
System.out.println("---Original Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
for (int i = 0; i < arr.length; i++) {
if (arr[i] == k)
count++;
}
for (int j = 0; j < count; j++) {
for (int i = 0; i < arr.length; i++) {
if(i >= arr.length - count){
arr[i] = 0;
}else {
if (arr[i] == k) {
for (int l = i; l < arr.length - 1; l++) {
arr[l] = arr[l + 1];
}
}
}
}
}
System.out.println("---Modified Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
}
Which gives output
---Original Array------
1 2 30 4 5 30 6
---Modified Array------
1 2 4 5 6 0 0
Now, we can simplify the code also
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 30, 4, 5, 30, 6 };
int k = 30;
int count = 0;
System.out.println("---Original Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
for(int i = 0; i < arr.length; i++){
if(arr[i]==k){
count++;
}else{
arr[i-count] = arr[i];
}
}
for(int i = 1; i <= count; i++){
arr[arr.length - i] = 0;
}
System.out.println("---Modified Array------");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
}
which give the same output

Finding the count of common array sequencce

I am trying to the length of the longest sequence of numbers shared by two arrays. Given the following two arrays:
int [] a = {1, 2, 3, 4, 6, 8,};
int [] b = {2, 1, 2, 3, 5, 6,};
The result should be 3 as the the longest common sequence between the two is{1, 2, 3}.
The numbers must be in a sequence for the program to consider to count it.
I have thought about it and wrote a small beginning however, I am not sure how to approach this
public static int longestSharedSequence(int[] arr, int[] arr2){
int start = 0;
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr2.length; j++){
int n = 0;
while(arr[i + n] == arr2[j + n]){
n++;
if(((i + n) >= arr.length) || ((j + n) >= arr2.length)){
break;
}
}
}
That is a very good start that you have. All you need to do is have some way of keeping track of the best n value that you have encountered. So at the start of the method, declare int maxN = 0. Then, after the while loop within the two for loops, check if n (the current matching sequence length) is greater than maxN (the longest matching sequence length encountered so far). If so, update maxN to the value of n.
Since you also want the matching elements to be in sequential order, you will need to check that the elements in the two arrays not only match, but that they are also 1 greater than the previous element in each array.
Putting these together gives the following code:
public static int longestSharedSequence(int[] arr, int[] arr2) {
int maxN = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr2.length; j++) {
int n = 0;
// Check that elements match and that they are either the
// first element in the sequence that is currently being
// compared or that they are 1 greater than the previous
// element
while (arr[i + n] == arr2[j + n]
&& (n == 0 || arr[i + n] == arr[i + n - 1] + 1)) {
n++;
if (i + n >= arr.length || j + n >= arr2.length) {
break;
}
}
// If we found a longer sequence than the previous longest,
// update maxN
if (n > maxN) {
maxN = n;
}
}
}
return maxN;
}
I didn't think of anything smarter than the path you were already on:
import java.util.Arrays;
import java.util.Random;
public class MaxSeq {
public static void main(String... args) {
int[] a = new int[10000];
int[] b = new int[10000];
final Random r = new Random();
Arrays.parallelSetAll(a, i -> r.nextInt(100));
Arrays.parallelSetAll(b, i -> r.nextInt(100));
System.out.println(longestSharedSequence(a, b));
}
private static int longestSharedSequence(final int[] arr, final int[] arr2) {
int max = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr2.length; j++) {
int n = 0;
while ((i + n) < arr.length
&& (j + n) < arr2.length
&& arr[i + n] == arr2[j + n]) {
n++;
}
max = Math.max(max, n);
}
}
return max;
}
}
see: https://en.wikipedia.org/wiki/Longest_common_subsequence_problem

Extract array elements to separate array

I have to make a program that extract every 3th element from array. So far i have made the basic array, but im stuck at extracting every 3th element into separate array. How can i do that?
public static void main(String[] args) {
int min = -100;
int max = 100;
int[] array = new int[201];
for( int i = 0; i < array.length; i++) {
array[i] = min + (int)(Math.random()*((max - min) + 1));
To fill in a new array (named array2) with every 3rd item from your array:
int[] array2 = new int[array.length / 3];
int k = 2;
for(int j = 0; j < array2.length; j++) {
array2[j] = array[k];
k += 3;
}
just make your for loop jump by three:
int[] newArray = new int[array.length / 3];
for (int i = 2 ; i < array.length ; i+=3) {
newArray[i/3] = array[i];
}

Categories

Resources