Java change the position of integers in an array - java

I have to introduce 10 integers in an array. For example int A[] = {1,2,3,4,5,6,7,8,9,10}. Then I have to print the array in normal order which is fine, and after I have to make each element of the array hop over to the next position and the last element to the first position. Assuming we have the same integers in the array as before the result would be this: A[] = {10,1,2,3,4,5,6,7,8,9}
Here's my code so far but I get the out of bounds error. Also I don't know how to flip the last element to the first position
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int A[] = new int[10];
System.out.println("Introduce the array numbers");
for (int i = 0; i < 10; i++) {
A[i] = sc.nextInt();
}
//array in normal order
for (int i = 0; i < 10; i++) {
System.out.print("["+A[i]+"]");
}
//here i have to print the modified array
System.out.println("");
for (int i = 0; i < 10; i++) {
System.out.print("["+A[i+1]+"]");
}
}

As stated, the goal is to start with this array:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
And to modify it such that you wind up with this:
[10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
What you are doing here, in essence, is pushing every number one spot to the right. The right-most number, when "pushed one spot to the right", will wrap around to the start of the array.
If we start by just taking the first number and copying it to the right, we run into a problem. The start of the array [1, 2] is now [1, 1]... which means we no longer know what number to push forward into the third slot. In other words, if we just blindly started at the beginning of the array and pushed numbers to the right, we'd wind up with this:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
The best way to solve this issue is to do our work starting at the end of the array, and then to work backwards. So first we push the 9 over to the right, then the 8, and so on.
Once we do that, the only problem is what we do with the first position. If we just moved everything over by one, we'd have this:
[???, 1, 2, 3, 4, 5, 6, 7, 8, 9]
To make matters worse, we might actually crash the program by trying to acces the "negative one-th" element to move it over to the zero index.
The best way around this is to break our problem up into three steps:
Save the last number in the array for later
For each position, starting from the end and working back to the second position, set the number to be equal to the number at the position before it
Set the first number in the array to the saved "last" number
Here's what that looks like in code:
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int last = numbers[numbers.length - 1]; // last now stores 10
// for index 9 to index 1, copy numbers to the right
for (int i = numbers.length - 1; i > 0; --i) {
numbers[i] = numbers[i - 1];
}
numbers[0] = last; // the first number is now 10

Related

Find minimum peak elements in an array

Question: Given an array numbers = {2, 7, 8, 5, 1, 6, 3, 9, 4}. Check the below conditions, both the conditions should be satisfied.
a[i] > a[i-1] or if first element a[i] > a[i+1]
a[i] > a[i+1] or if last element a[lastelement] > a[lastelement - 1]
Therefore:
1st Iteration - 8, 6, 9 are peak values. Remove the smallest ele. Remove 6. New arr {2, 7, 8, 5, 1, 3, 9, 4}. Output Arr - {6}
2nd Iteration - 8, 9 are peak values. Remove the smallest ele. Remove 8. New arr {2, 7, 5, 1, 3, 9, 4}. Output Arr - {6, 8}
3rd Iteration - 7, 9 are peak values. Remove the smallest ele. Remove 7. New arr {2, 5, 1, 3, 9, 4}. Output Arr - {6, 7, 8}
4th Iteration - 5, 9 are peak values. Remove the smallest ele. Remove 5. New arr {2, 1, 3, 9, 4}. Output Arr - {6, 7, 8, 5}
5th Iteration - 2, 9 are peak values. Remove the smallest ele. Remove 2. New arr {1, 3, 9, 4}. Output Arr - {6, 7, 8, 5, 2}
6th Iteration - 9 are peak values. Remove the smallest ele. Remove 9. New arr {1, 3, 4}. Output Arr - {6, 7, 8, 5, 2, 9}
7th Iteration - 4 are peak values. Remove the smallest ele. Remove 4. New arr {1, 3}. Output Arr - {6, 7, 8, 5, 2, 9, 4}
8th Iteration - 3 are peak values. Remove the smallest ele. Remove 3. New arr {1}. Output Arr - {6, 7, 8, 5, 2, 9, 4, 3}
9th Iteration - 1 are peak values. Remove the smallest ele. Remove 1. New arr {1}. Output Arr - {6, 7, 8, 5, 2, 9, 4, 3, 1}
Output: {6, 8, 7, 5, 2, 9, 4, 3, 1}
My solution is working but I am looking for optimized solution. Please let me know.
Here is my code:
public int[] findMinimumPeaks(int[] arr){
List<Integer> list1 = new ArrayList<Integer>(arr.length);
int[] output = new int[arr.length];
for(int i: arr)
list1.add(i);
for(int i =0; i<arr.length; i++){
int minIndex = minimumPeakElement(list1);
output[i] = list1.get(minIndex);
list1.remove(minIndex);
}
return output;
}
public int minimumPeakElement(List<Integer> list1){
int minIndex = 0, peakStart = Integer.MAX_VALUE, peakEnd = Integer.MAX_VALUE;
int peak = Integer.MAX_VALUE, minPeak = Integer.MAX_VALUE;
if(list1.size() >= 2){
if(list1.get(0) > list1.get(1)) peakStart = list1.get(0);
if(list1.get(list1.size() - 1) > list1.get(list1.size() - 2)) peakEnd = list1.get(list1.size() - 1);
if(peakStart < peakEnd){
minPeak = peakStart;
minIndex = 0;
}
else if(peakEnd < peakStart){
minPeak = peakEnd;
minIndex = list1.size() - 1;
}
}
for(int i=1; i<list1.size() - 1; i++){
if(list1.get(i) > list1.get(i + 1) && list1.get(i) > list1.get(i-1)) peak = list1.get(i);
if(peak < minPeak){
minPeak = peak;
minIndex = i;
}
}
return minIndex;
}
Here is an idea how to optimize asymptotic complexity.
Use single pass over elements of your initial array to split it into "up-down" "slopes" or "hills", i.e. subsequence of elements in ascending order, followed by subsequence in descending order.
Store these slopes in the following datastructure:
val slopes = MinPriorityQueue<Slope>()
class Slope(
var first: Int, // first element of the slope
var last: Int, // last element of the slope
var peak: Int, // max or peak element
var els: MaxPriorityQueue<Int>(), // all elements of the slope
var prev: Slope?, // link to the previous slope in the list or null if first
var next: Slope? // link to the next slope in the list or null if last
)
Slopes should be comparable by their peak value.
Now, having this data structure, you can poll the slope that has minimal peak value in O(log(N)). After you polled the slope, you should update the slope by removing it's peak element (i.e. poll els, then update first, last, peak), also, slope might become eligible to be merged with the previous or next slope:
Admittedly, this solution is not an easy one, having a lot of things to maintain and large number of corner cases. However, it's much better in terms of asymptotic complexity.
Initial data structure build: O(n log(n))
Polling elements while maintaining slopes: O(n log (n))
Overall complexity: O(n log(n))
Notes:
One of the corner cases, if array can have duplicate elements, then inner priority queue (els) becomes MaxPriorityQueue<Pair<Int,Int>>, i.e. you need to store the number of potentially duplicate elements along with the element value.
MinPriorityQueue and MaxPriorityQueue is an abstract heap-based data structure with min and max element at the head respectively. Can be implemented with PriorityQueue in java

How do I count repeated occurrences of an element in a list?

Say I have an arraylist = [1, 1, 1, 1, 1, 5, 5, 6, 3, 5, 6 2, 5, 1 , 1, 1, 1, 1, 4, 2, 4, 2, 5 ,2 ,6 ,3,5, 2, 5, 1 , 1, 1, 1, 1, 1, 4, 1, 5, 2,]
I would like to find all the start indexes of a sequence of x.
The sequence length must be > 2
For example x = 1
My expected output is this:
start at element 0, interval of size 5.
start at element 13, interval of size 5.
start at element 29, interval of size 6.
I am new to programming in java and I don't know what the logic would be.
I was thinking of using a for loop and looping through each element in the array and using a counter when the element i == 1. My problem is I'm not sure how to stop counting and resume counting between intervals.
public void count() {
int count = 0;
for(Integer number: ArrayList) {
if (number == 1 ) {
count++;
}
if (number != 1 ) {
break;
}
}
}
As you can see my attempts are pretty bad. I'm missing something crucial and just can't see it.
Please check sliding window approach:
https://medium.com/outco/how-to-solve-sliding-window-problems-28d67601a66
In general, you should use 2 pointers in the array,
The first one will indecte the beginning of the sequence, the second one will indecte about the length or the sequence.
You start moving with that start index untill you getting to you value, then moving with the second index untill reaching to a different number.
Then you record you result bye saving Pair of start index and length inside an ArrayList or any structure, and setting the startIndex =endindex+1
You can visit leetcode / geeksforgeeks for more related questions and topics
Try this
import java.util.*;
public class Main
{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
List<Integer> numbers = new ArrayList<Integer>();
numbers.addAll(Arrays.asList(1, 1, 1, 1, 1, 5, 5, 6, 3, 5, 6, 2, 5, 1, 1, 1, 1, 1, 4, 2, 4, 2, 5 ,2 ,6 ,3,5, 2, 5, 1, 1, 1, 1, 1, 1, 4, 1, 5, 2));
int startIndex = -1;
int count = 0;
System.out.print("Enter a number to count: ");
int x = scan.nextInt();
numbers.add(x-1);
for(int i = 0; i < numbers.size(); i++){
if(numbers.get(i) == x){
if(count == 0)
startIndex = i;
count++;
} else{
if(count > 2)
System.out.printf("start at index %d, interval of size %d \n", startIndex, count);
count = 0;
}
}
}
}
Output:
Enter a number to count: 1
start at index 0, interval of size 5
start at index 13, interval of size 5
start at index 29, interval of size 6
I am new to programming in java
...but this is not related to java, is it?
I don't know what the logic would be.
That's what you need to solve before trying to implement it.
Hint: Can you implement something slightly different? Change the input to number occurrences of 1s in a list, so your output would be [5, 5, 6, 1].
Hint 2: sometimes it's easier to add extra number (terminator) to original list, so let say if -1 cannot be there, add -1 to the end, so once you find -1, you know you are at the end...

Is it possible to remove an index from a object array?

I have seen you can do this using ArrayLists, but is it possible to do this using a normal object array?
deleting an object from an array [java]
At the start of each the player is given 3 random dice from a cup.
The cup has 13 dice in total.
When the player is given the 3 dice from the cup the cup should have only 10 dice in left. I was trying to set the value to null but this still counts as a index in the array so the length does not change.
// Removing the 3 dice which were picked form the cup of the current player, the diceToTakeOut is a String array with a length of 3 the newTurnCup is a Object array with a length of 13
public static Dice [] cup(String [] diceTotakeOut, Dice [] newTurnCup){
for (int i = 0; i < diceTotakeOut.length; i++) {
if (diceTotakeOut.length > 0) {
if (diceTotakeOut[i] == newTurnCup[i].getName()) {
newTurnCup[i] = null;
}
}
}
return newTurnCup;
}
I have tried a few different ways which I could think of:
newTurnCup[i] = null;
newTurnCup[i] = newTurnCup[i - 1];
The result would be after each turn the array holding the dice would have 3 index less.
It's not doable since the array has a fixed size.
But try using an ArrayList which allow you to remove elements dynamically using the method remove(int index)
or:
shift the content of the array starting from the targeted index to the end. (shift: left to right).
An array variable in Java is a pointer to a zone of memory directly proportionate to it's capacity and the size of the type it contains. This area cannot be dynamically modified. The only way to do what you want is to create a new array variable that has allocated the new size of array you want. This is what happens behind the scenes also in the Collections that implement this functionality just that there are optimisations in place in order to do this (potentially very costly) operations only when it is needed.
So my best suggestion would be to change your design to use Lists, ArrayLists for example. LinkedLists, althought they came out as a nice idea, in practice are generally avoided because they are in fact slower (they don't take advantage of hardware memory caching).
You can't do this cleanly with an array; you would have to recreate a shorter array every time.
You can do it with other data structures, for example a LinkedList.
Since you are working with array and not ArrayList, you can achieve this by creating a work around.
public static Dice[] removeTheElement(Dice[] arr, int index) {
// If the array is empty
// or the index is not in array range
// return the original array
if (arr == null
|| index < 0
|| index >= arr.length) {
return arr;
}
// Create another array of size one less
Dice[] anotherArray = new Dice[arr.length - 1];
// Copy the elements except the index
// from original array to the other array
for (int i = 0, k = 0; i < arr.length; i++) {
// if the index is
// the removal element index
if (i == index) {
continue;
}
// if the index is not
// the removal element index
anotherArray[k++] = arr[i];
}
// return the resultant array
return anotherArray;
}
So in here, we pass as a parameter the Object that we are working with, and the index of the array that we like to remove. We create a temporary Object inside to our function and return it without the element with the index number that we provided.
You can't do that. In Java an array is an immutable object. Once created, the size of this array cannot be changed (sure you could modify array items).
To have a collection with the various size you should use List collection: ArrayList - this is based on an internal array with additional property - size, LinkedList.
List<Dice> dices = new ArrayList<>(); // dices.size() -> 0
dices.add(null); // dices.size() -> 1
dices.add(null); // dices.size() -> 2
dices.remove(0); // dices.size() -> 1
To make array immutability clear, this is an example of how manually remove an item from an array:
public static Dice[] removeItem(Dice[] dices, int i) {
if (dices == null || dices.length == 0)
return dices;
if (i < 0 || i >= dices.length)
throw new ArrayIndexOutOfBoundsException();
Dice[] res = new Dice[dices.length - 1];
System.arraycopy(dices, 0, res, 0, i);
System.arraycopy(dices, i + 1, res, i, dices.length - i - 1);
return res;
}
Dice[] arr = null;
arr = removeItem(arr, 5);
As mentioned in other answers, you cannot remove an element from an array directly. You need to write a custom method which will copy all the elements except the one which you need to remove.
However, I suggest you should use ArrayUtils from Apache Commons.
ArrayUtils.remove(array, index)
Some examples from the docs:
ArrayUtils.remove(["a", "b"], 0) = ["b"]
ArrayUtils.remove(["a", "b"], 1) = ["a"]
Refer: ArrayUtils Documentation
Your best bet is to use ArrayList and then after manipulating getting array out of it.
If you want to get your hands dirty and are accepting that you have to create new array, you can do the following:
private static String[] removeIndex(String[] inputArray, int indexToRemove){
if (indexToRemove >= inputArray.length) {
throw new IndexOutOfBoundsException("index " + indexToRemove + " is not allowed for array with size=" + inputArray.length);
}
String[] resultArray = new String[inputArray.length - 1 ];
System.arraycopy(inputArray, 0, resultArray, 0, indexToRemove);
System.arraycopy(inputArray, indexToRemove + 1, resultArray, indexToRemove, resultArray.length - indexToRemove);
return resultArray;
}
And then consuming it:
String[] inputArray = new String[]{"1","2","3","4","5","6","7","8","9","10"};
System.out.println(Arrays.toString(removeIndex(inputArray, 0)));
System.out.println(Arrays.toString(removeIndex(inputArray, 1)));
System.out.println(Arrays.toString(removeIndex(inputArray, 2)));
System.out.println(Arrays.toString(removeIndex(inputArray, 3)));
System.out.println(Arrays.toString(removeIndex(inputArray, 4)));
System.out.println(Arrays.toString(removeIndex(inputArray, 5)));
System.out.println(Arrays.toString(removeIndex(inputArray, 6)));
System.out.println(Arrays.toString(removeIndex(inputArray, 7)));
System.out.println(Arrays.toString(removeIndex(inputArray, 8)));
System.out.println(Arrays.toString(removeIndex(inputArray, 9)));
System.out.println(Arrays.toString(removeIndex(inputArray, 10)));
produces:
[2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Exception in thread "main" java.lang.IndexOutOfBoundsException: index 10 is not allowed for array with size=10
at Scratch.removeIndex(scratch.java:81)
at Scratch.main(scratch.java:73)

Logic to remove first n elements from an array

One of the methods that I need to write for an assignment is supposed to remove the first n elements from an array. However, I am not getting the correct output. I believe I'm having an off by one error, but I am not exactly sure how to fix it.
Solutions should try to maintain the format of the code as closely as possible.
for (int i = n; i >= 0; i--) {
elementData[i] = elementData[i + 1];
size--;
}
What the code is saying is that, for every element n and below, replace it with whatever is in the index higher than it. Then reduce the size variable for every time that you do this, which should result in it looking like a remove operation when printed.
I expected the output of [0, 1, 2, 4, 6, 4, 7] to be [4, 7].
However, I got [7].
n is passed as 5 in the above case.
I realize this is an assignment question looking for an implementation, but anyone doing this in Java should use the provided APIs. For example:
public int[] trimArray(int[] source, int trimBy) {
if (trimBy > source.length) return source;
return Arrays.copyOfRange(source, trimBy, source.length);
}
trimArray(new int[]{0, 1, 2, 4, 6, 4, 7}, 5) // -> [4, 7]
You can just use this:
int[] result = new int[elementData.length - n];
for (int i = 0; i < result.length; i++) {
result[i] = elementData[n + i];
}
Which is an extended form of this:
int[] result = new int[elementData.length - n];
System.arraycopy(elementData, n, result, 0, result.length);
You can use filter:
let a = [0, 1, 2, 4, 6, 4, 7]
you want to obtain [4, 7] removing 5 first elements so type
a = a.filter((_, i) => i >= 5)
Now
a = [4, 7]
elementData = Arrays.copyOfRange( elementData, n, elementData.length ); // originalArray, startIndex, end

How to auto generate overlapping integers in a certain range

If the number range is 0 - 10. I would like to generate the following numbers
e.g.
unique 5 numbers [3, 8, 5, 1, 9]
unique 3 numbers [2, 6, 5]
5 numbers of which 2 numbers occur twice [2, 3, 2, 6, 3]
7 numbers of which 2 numbers occur twice [2, 5, 9, 2, 7, 5, 3] (Here 2, 5 occur twice)
5 numbers of which 1 number occur thrice [2, 3, 8, 3, 3] (Here 3 occurs twice)
7 numbers of which 1 number occur thrice and 1 number occurs twice [1, 5, 9, 1, 1, 5, 3] (Here 1 occurs thrice, 5 occurs twice)
How would you implement a generic function which caters to the above requirements.
EDIT1:
This is what I have right now..
protected List<Integer> fetchOverlapIntegers(int min, int max,
int howMany, int overlap) {
// The following code fetches unique numbers within the range
List<Integer> numbers = this.fetchRandomIntegers(min, max, howMany);
if (overlap > 0) {
int size = numbers.size();
for (int i = 0; i < overlap; i++) {
numbers.set(size - 1 - i, numbers.get(i));
}
}
Collections.shuffle(numbers);
return numbers;
}
Just for grins I wrote this up for this very underspecified problem:
public static List<Integer> weirdFunction(List<Integer> criteria, List<Integer> candidateNumbers) {
List<Integer> results = new ArrayList<Integer>();
for (int occurrenceCount = 0; occurrenceCount < criteria.size(); occurrenceCount++) {
int thisMany = criteria.get(occurrenceCount);
for (int i=0; i < thisMany; i++) {
Integer theChoice = candidateNumbers.get(new Random().nextInt(candidateNumbers.size()));
for (int ct=0; ct < occurrenceCount; ct++) {
results.add(theChoice);
}
}
}
Collections.shuffle(results);
return results;
}
It takes two lists, one which is the criteria which is basically a list of how many times it'll place a randomly chosen number in the results (the 1st one gets chosen once, the 2nd twice, etc.), and a list of candidateNumbers from which they'll be chosen.
But, this way only allows you to specify one particular "count" for each criteria. e.g. you can't have a list where "two numbers appear twice" because "appear twice" only has one slot. You could make this a list of lists or some other data structure of course.
Also, it doesn't eliminate duplicates when it pulls them in. So if we had a criteria of {1, 1, 1} it'd try and pull one number once, one number twice, and one number thrice. But it doesn't check if any of those are the same number - so it could end up pulling the same number each time and effectively pulling just one number six times instead of 3 separate numbers once, twice, and thrice.
You can randomly pull out items from the list of contender values, for example:
List<int> numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Random r = new Random();
for (int i = 0; i < 4; i++)
{
int index = r.Next() % numbers.Count;
Console.WriteLine(numbers[index]);
numbers.RemoveAt(index);
}
If you want a value tripled, just triple the first removed. Then shuffle your results at the end.

Categories