Related
If there is no odd value to the right of the zero, leave the zero as a zero.
zeroMax([0, 5, 0, 3]) → [5, 5, 3, 3]
zeroMax([0, 4, 0, 3]) → [3, 4, 3, 3]
This is from CodingBat: https://codingbat.com/prob/p187050
There are certainly better implementations than mine, but it would help me tremendously to see where I went wrong.
It is the findAndReplace method that is not doing its job. I don't see a reason as to why it insists that intarray[0] = 0, and that is where I am stuck. I have implemented the method separately from this class, and it works as expected.
Below is my work:
public class ZeroMax {
public static int[] zeroMax(int[] intarray) {
int max = largestOdd(intarray);
System.out.println("largest odd is " + max);
return findAndReplace1(intarray, 0, max);
}
//method returns the largest odd value or returns zero
public static int largestOdd(int[] arr) {
int maxodd = 0;
int n = arr.length;
int temp = 0;
//this is just a bubble sort
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n - i); j++) {
if (arr[j - 1] > arr[j]) {
//swap elements
temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
//this finds the largest number that is an odd
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] % 2 != 0) {
maxodd = arr[i];
break;
} else {
continue;
}
}
return maxodd;
}
//following returns an array where the zeros (int find)
// can be replaced with the largest odd (int replace)
public static int[] findAndReplace1(int[] intarray, int find, int replace) {
for (int i = 0; i < intarray.length; i++) {
//System.out.println(intarray[i]);
if (intarray[i] == find) {
intarray[i] = replace;
}
}
return intarray;
}
}
I believe that the key to your problem is
… to the right of the zero in the array
One given example is zeroMax([0, 5, 0, 3]) → [5, 5, 3, 3]. In your code you are finding the greatest odd value in the entire array. 5 in this case. Then you are replacing every 0 in the array with 5.
Original array: [0, 5, 0, 3]
Expected result: [5, 5, 3, 3]
Your result: [5, 5, 5, 3]
So it seems that you still have a bit of coding to do.
There are certainly better implementations than mine, …
Your implementation, your design and code style, are just fine. Only except for the lamentable fact that it didn’t solve the problem correctly.
An idea how to solve the problem. The following should work in all cases:
Iterate backward from the end array until the first (so the rightmost) odd number.
If there isn’t any odd number in the array, you’re done.
Store the odd number into a variable holding the greatest odd number encountered so far.
Continue iterating backward from the index you came to down to index 0. For each index:
If the number at the index is odd and greater than the hitherto greatest odd number, store the number as the greatest odd number.
If the number is 0, store the greatest odd number until now into the array at this index.
I was reading the question wrong. This is the successful solution that I came up with after more careful reading:
public int[] zeroMax(int[] intarray) {
int maxvalue = 0;
int index = 0;
for (int i = 0; i < intarray.length; i++) {
if (intarray[i] == 0) {
index = i;
//call max value method
maxvalue = maxvalue(intarray, index);
intarray[i] = maxvalue;
}
}
return intarray;
}
public int maxvalue(int[] intarray, int index) {
int maxvalue = 0;
for (int i = index; i < intarray.length; i++) {
if ((intarray[i] % 2 == 1) && (intarray[i] > maxvalue)) {
maxvalue = intarray[i];
}
}
return maxvalue;
}
You can use Arrays.stream(T[],int,int) method to iterate over this array from the current index to the end, then filter odd numbers and get max of them:
public static void main(String[] args) {
int[] arr1 = {0, 5, 0, 3};
int[] arr2 = {0, 4, 0, 3};
int[] arr3 = {0, 3, 0, 4};
replaceZeros(arr1);
replaceZeros(arr2);
replaceZeros(arr3);
System.out.println(Arrays.toString(arr1)); // [5, 5, 3, 3]
System.out.println(Arrays.toString(arr2)); // [3, 4, 3, 3]
System.out.println(Arrays.toString(arr3)); // [3, 3, 0, 4]
}
private static void replaceZeros(int[] arr) {
// iterate over the indices of array
IntStream.range(0, arr.length)
// filter zero elements
.filter(i -> arr[i] == 0)
// for each zero iterate over the elements
// of array from the current index to the end
.forEach(i -> Arrays.stream(arr, i, arr.length)
// filter odd elements
.filter(e -> e % 2 != 0)
// take the max element and
// replace the current one
.max().ifPresent(e -> arr[i] = e));
}
Currently working on an algorithm that replaces every element with the next greatest element, but unlike some other questions here, this one is not concerned with replacing values with -1 if no such number exists, and it must be in ascending order.
Given this input: {1, 5, -3, 2, 8, 4, 7, 10, 3, 11, 2 }
Have to get this output: 1 5 5 5 8 8 8 10 10 11 11
This is what I have so far:
class Playground {
static void nextGreatest(int arr[]) {
int size = arr.length;
// Initialize the next greatest element
int max_from_right = arr[size - 1];
// Replace all other elements with the next greatest
for (int i = 1; i < size; i++)
{
// Store the current element (needed later for
// updating the next greatest element)
int temp = arr[i];
// Replace current element with the next greatest
arr[i] = max_from_right;
// Update the greatest element, if needed
if(max_from_right < temp) {
max_from_right = temp;
}
}
}
// prints the array
static void printArray(int arr[])
{
for (int i=0; i < arr.length; i++)
System.out.print(arr[i]+" ");
}
public static void main (String[] args) {
int arr[] = {1, 5, -3, 2, 8, 4, 7, 10, 3, 11, 2 };
nextGreatest (arr);
printArray (arr);
}
}
And I get the following right now:
1 2 5 5 5 8 8 8 10 10 11
Thoughts?
Thanks
(Not sure I understand your question exactly, but based on the clarification from the comments here is my answer...)
Seems you just need to change the initial max initialization to the first element rather than the last element.
int currentMax = arr[0];
for (int i = 1; i < size; i++) {
int temp = arr[i];
arr[i] = currentMax;
if(currentMax < temp) {
currentMax = temp;
}
}
The solution ends up as For each index i, what is the maximum element seen so far.
Consider the following:
int currMax = -1;
int[] input = {1, 5, -3, 2, 8, 4, 7, 10, 3, 11, 2};
for (int i = 0; i < input.length; i++){
if (input[i] > currMax){ // if we find a new max element
currMax = input[i];
}
else if (input[i] < currMax){ // if value is less then max we replace it
input[i] = currMax;
}
}
System.out.println(Arrays.toString(input));
> [1, 5, 5, 5, 8, 8, 8, 10, 10, 11, 11]
I am currently practicing algorithm development with Java and have recently really got stuck on a particular problem. I have been challenged to develop two different algorithm.
My task is to solve the selection problem. the selection problem determines the kth largest number in a group of N numbers.
I have successfully implemented the first algorithm. I read the N numbers into an array, sort the array in decreasing order by some simple algorithm, and then return the element in position k.
Note: k = N / 2
Here is the working code
public int selectionAlgorithmOne() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
//I sort the array of size N in decreasing order
bubbleSortDecreasingOrder(intArray);
//{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
//I obtain the value of k
int k = intArray.length / 2;
//I print the result
System.out.println(intArray[k]);
}
The value that is printed in "5" which is correct! However, the second algorithm is a bit trickier.
Read the first k elements into an array and sort them in decreasing order. Next, each remaining element is read one by one. As a new element arrives, it is ignored if it is smaller than the kth element in the array. Otherwise, it is placed in its correct spot in the array, bumping one element out of the array. When the algorithm ends, the element in the kth position is returned as the answer.
Unfortunately my second algorithm does not work. It returns the value "3" which is wrong. It should be returning the same value of "5" as the first algorithm but in a more efficient.
I have been stuck for a few days now and I am really struggling to find the solution. Hopefully I have given the problem enough context, let me know if I can provide any more information. Thanks in advance.
Here is the non-working code
public int selectionAlgorithmTwo() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
int arrayLength = intArray.length;
int k = arrayLength / 2;
int[] firstHalf = new int[k];
//I read the first half of the elements into an array
for (int i = 0; i < k; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for(int i = k; i < arrayLength; i++) {
int val = intArray[i];
//If the new element to insert is >= the kth largest
if (val > firstHalf[k - 1]) {
int pos = 0;
for(; pos < k; pos++) {
if(val > firstHalf[pos]) {
break; //I break once I have the correct position located
}
//I make the swap
for (int j = k - 1; j > pos; j--)
firstHalf[j] = firstHalf[j - 1];
firstHalf[pos] = val;
}
}
}
return firstHalf[k - 1];
}
First of all, "the element in position k" isn't the kth element, it's the k+1 th element. Indeed 5 is the sixth element of the sorted array.
So, if you want to return the element in position k, you need an array of k+1 element.
Therefore I added the firstHalfLen variable.
If you use an array of k element, you'll never get 5 as answer.
In the block if (val > firstHalf[k]), in order to find the correct index, I preferred a while loop
while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
pos++;
}
Then the swap:
for (int j = k; j > pos; j--) {
firstHalf[j] = firstHalf[j - 1];
}
Code:
int[] intArray = new int[] { 1, 7, 9, 8, 2, 3, 5, 4, 6, 10 };
int arrayLength = intArray.length;
int k = arrayLength / 2;
int firstHalfLen = k + 1;
int[] firstHalf = new int[firstHalfLen];
// I read the first half of the elements into an array
for (int i = 0; i < firstHalfLen; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for (int i = firstHalfLen; i < arrayLength; i++) {
int val = intArray[i];
// If the new element to insert is >= the kth largest
if (val > firstHalf[k]) {
int pos = 0;
// find index
while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
pos++;
}
// Swap
for (int j = k; j > pos; j--) {
firstHalf[j] = firstHalf[j - 1];
}
firstHalf[pos] = val;
}
}
return firstHalf[k];
You are comparing values from the unsorted part to values of the sorted part, starting low, i.e. at small values. The probability that the value is larger than the first sorted value is quite high. More interesting would be a value which is smaller. According to your algorithm, the smaller unsorted value should be inserted into the small sorted values, at the position where it replaces a higher value, not a smaller one.
So
if(val > firstHalf[pos])
should be
if(val < firstHalf[pos])
Try this code:
public int sortTest() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
int arrayLength = intArray.length;
int k = arrayLength / 2;
int[] firstHalf = new int[k];
//I read the first half of the elements into an array
for (int i = 0; i < k; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for(int i = k; i < arrayLength; i++) {
int val = intArray[i];
//If the new element to insert is >= the kth largest
if (val > firstHalf[k - 1]) {
int pos = 0;
for(; pos < k; pos++) {
if(val > firstHalf[pos]) {
break; //I break once I have the correct position located
}
}
//I make the swap
for (int j = k - 1; j > pos; j--)
firstHalf[j] = firstHalf[j - 1];
firstHalf[pos] = val;
}
}
return firstHalf[k - 1];
}
The error in your code is that, after you found the correct position and break, you leave the for loop without the swap procedure.
Also note that this code return 6, not 5, because you returned the k-1 th value.
I'm trying to solve this problem from CodingBat.
We'll say that a "mirror" section in an array is a group of contiguous
elements such that somewhere in the array, the same group appears in
reverse order. For example, the largest mirror section in {1, 2, 3, 8,
9, 3, 2, 1} is length 3 (the {1, 2, 3} part). Return the size of the
largest mirror section found in the given array.
maxMirror([1, 2, 3, 8, 9, 3, 2, 1]) → 3 maxMirror([1, 2, 1, 4]) → 3
maxMirror([7, 1, 2, 9, 7, 2, 1]) → 2
public int maxMirror(int[] nums)
{
int count = 0;
int max = 0;
int min = 0;
String abc = "";
for(int i=0; i<nums.length; i++)
{
abc += nums[i];
}//
for(int i=0, k = abc.length(); i<abc.length(); i++, k--)
{
for(int j=i, l = abc.length()-i; j<abc.length(); j++, l--)
{
if(abc.substring(i,j).equals(abc.substring(k,l)))
min = abc.substring(i,j).length();
if(min > max)
max = min;
}
}
count = max;
return count;
}
I thought inserting the all elements of an array into a string is a very good idea, since string class has its own functions such as substring.
I think my algorithm to this problem is simple, flexible and reliable but it doesn't work as i thought. I'm getting exception errors which complains about the bounds of the string.
What should i do?
I also toyed with the idea of a reverse/compare algo, but it's still going into O(n^..), so I settled on this solution. The idea here is for each int element moving forward in the array, we begin to iterate backward from the end. If we get a match, we go into the while()loop, continuing to compare and increment our size variable until they no longer match. From there, it's a simple matter of comparing to our max variable, updating max to either itself or var size,(whichever is higher) eventually returning max.
public int maxMirror(int[] nums) {
int max = 0;
for(int left = 0; left < nums.length; left++) {
for(int right = nums.length -1; right >= 0; right--) {
int size = 0;
int i = left;
int j = right;
while(i < nums.length && j >= 0 && nums[i] == nums[j]) {
size++;
i++;
j--;
} max = Math.max(max, size);
}
} return max;
}
This question already has answers here:
How to efficiently remove duplicates from an array without using Set
(48 answers)
Closed 7 years ago.
I was asked to write a method that accepts a sorted array, removes any duplicate elements found in the array and then places a 0 at the end of the array for every duplicate element found.
It is also supposed to return the number of unique elements found in the array.
Here is my method:
public static int removeDups(int[] arr) {
int j = 0;
int i = 1;
int numDups = 0;
while(i < arr.length) {
if (arr[i] == arr[j]) {
i++;
numDups++;
}
else {
arr[++j] = arr[i++];
}
}
for (int k = j+1; k < arr.length; k++) {
arr[k] = 0;
}
return (j);
}
It successfully finds all the duplicate numbers in the array and places the correct number of 0s at the end, but it doesn't always return the correct value for the number of unique elements.
For example, for the array:
{ 6 10 19 21 23 26 27 36 38 45 }
the number of unique elements should be 10, but it returns 9.
What am I doing wrong?
As it can be seen, j is used as the index of the last unique element.
In an array, i'th index is actually the i + 1'th element counted from 1.
So, you have to return j + 1 instead of j from your method.
Here is a solution to your problem. It keeps track of two pointers, one which only advances when a value gets written to the array, and the other which touches every element of the array in sequential order. When one or more duplicates are encountered, the second pointer keeps advancing, while the first pointer stays put, waiting to write a non-duplicate value. Finally, the code iterates over the remainder of the array from the first pointer, writing out zeroes until the end.
public static int removeDups(int[] arr) {
if (arr == null) {
return null;
}
if (arr.length == 0 || arr.length == 1) {
return arr;
}
int prevIndex = 0;
for (int i=1; i < arr.length; ++i) {
if (arr[prevIndex] != arr[i]) {
arr[prevIndex+1] = arr[i];
++prevIndex;
}
}
for (int i=prevIndex+1; i < arr.length; ++i) {
arr[i] = 0;
}
return prevIndex+1;
}
int[] arr = {1, 2, 3, 3, 4, 5, 6, 6, 6, 10};
removeDups(arr);
System.out.println(Arrays.toString(arr));
Output:
[1, 2, 3, 4, 5, 6, 10, 0, 0, 0]
This code has been tested using IntelliJ and it appears to be working.
Try this!
static int getUniqueElements(int [] sortedArr){
int duplicateCount = 0;
int [] tempArr = sortedArr;
int j=0;
boolean isNewValue = true;
for(int i=1;i<tempArr.length;i++){
if(sortedArr[j] != tempArr[i]){
isNewValue = true;
sortedArr[++j] = tempArr[i];
}else{
if(isNewValue){
isNewValue = false;
duplicateCount++;
}
}
}
for(j++;j<sortedArr.length;j++){
sortedArr[j] = 0;
duplicateCount++;
}
return (sortedArr.length-duplicateCount);
}
public static void main(String[] args) {
int[] arr = {1, 3, 3, 3, 3, 6, 6, 7, 8, 8};
System.out.println("Unique Count:"+ getUniqueElements(arr));
System.out.println(Arrays.toString(arr));
}
OutPut:
Unique Count:2
[1, 3, 6, 7, 8, 0, 0, 0, 0, 0]
Since in the given array 1,7 are unique.
Note: tried with your example array {6, 10, 19, 21, 23 ,26 ,27 ,36 ,38, 45 } also
My solution is as(assuming elements can repeat only twice):
public static int removeDups(int[] arr) {
int i = 0;
int numDups = 0;
while (i < arr.length - 1 - numDups) {
if (arr[i] == arr[i + 1]) {
numDups++;
for (int m = i + 1; m < arr.length - numDups; m++) {
arr[m] = arr[m + 1];
}
arr[arr.length - numDups] = 0;
}
i++;
}
return arr.length-numDups;
}