Java find value in column wise sorted matrix - java

I am currently in my first year of university and my teacher gave us an interesting problem
Given the 2 dimensional array m (the column length is equal to the row length for example 4x4, 3x3)
We know that if m goes through the function test it will return true
Now we need to write a function that based on that information will find the given value in m and return false or true if was found. In addition, the function must be with time complexity of O(n) or less when n is the length of row/column (For example if the matrix is 5x5 then n is 5). The function cannot use recursion
Here is function test:
public static boolean test(int [][] m)
{
int n=m.length;
for(int r=0; r<(n-1); r++)
for (int c=0; c<n; c++)
for (int i=0; i<n; i++)
if(m[r][c] > m[r+1][i]) return false;
return true;
}
Here is an example for a matrix that I came up with that returns true:
1, 3, 2, 5
10, 9, 7, 15
17, 25, 16, 20
50, 30, 28, 40
Here is a possible function signature:
public static boolean findValTest (int [][] m, int val)
Thanks for everyone who answers!

Update: Here's an O(nlogn) solution, we need further discussion to find a number in one column in O(1).
public static boolean findValTest(int[][] m, int val) {
for (int c = 0; c < m.length; c++) {
if (val < m[c][0] || val > m[c][m[c].length - 1]) continue;
if (binarySearch(m, c, val)) return true;
}
return false;
}
private static boolean binarySearch(int[][] m, int col, int key) {
int low = 0, high = m[col].length - 1;
while (low <= high) {
int mid = low + ((high - low) / 2);
if (m[mid][col] < key) {
low = mid + 1;
} else if (m[mid][col] > key) {
high = mid - 1;
} else if (m[mid][col] == key) {
return true;
}
}
return false;
}

I have managed to figure it out. It is basically O(3n) but since 3 is constant it is O(n).
Basically we use the first column to give us the index of two rows where the value might be in.
For example if we use the matrix we I gave as an example and the value is 16 we go like this:
Is val between 1 and 10? No.
Is val between 10 and 17? Yes
Search second row and third row.
Here is the code(It is kinda long and ugly but hopefully you will understand it):
// We search in the first column between what two numbers the value is,
// Then we search for row of the first index, if not there we search the row of the other index
// Time Complexity: O(n). We go through the first column which is O(n) and then we go over 2 rows which is O(2n). Together its O(3n) but because 3 is constant the time is O(n)
public static boolean findValTest(int[][] m, int val) {
int[] index = whichRows(m,val);
if(index[0] == -1 && index[1] == -1) // Indicator that the number was found in the first column
return true;
if(index[1] == -1){
// We search in only one row
for(int i = 0; i < m.length - 1; i++){
if(val == m[index[0]][i]) {
return true;
}
}
}
else {
// Search both given rows by index
for(int i = 0; i < index.length; i++){
for(int j = 0; j < m.length; j++) {
if(val == m[index[i]][j])
return true;
}
}
}
return false;
}
public static int[] whichRows(int[][] m, int val) {
int[] index = {0,0}; int len = m.length;
// -1 in the index indicates that only one row needs to be searched, or the first or the last
if(m[len-1][0] < val) // Only the last row(Which contains the biggest numbers in the matrix) needs to be searched
{
index[0] = len-1; index[1] = -1;
}
else if(m[0][0] > val){ // Only the first row needs to be searched
index[0] = 0; index[1] = -1;
}
else { // We search between
for(int i = 0; i < len - 1; i++){
if(m[0][i] == val)
{
index[0] = -1; index[1] = -1;
return index;
}
if(m[i][0] < val && val < m[i+1][0]){
index[0] = i; index[1] = i +1;
break;
}
}
}
return index;
}

just wanted to update you that your code doesn't work at certain times.
Wanted to give you a breakdown but unfortunately something came up and I will have to go for the next couple of days, so it is my hope that you fix whatever's plaguing your design.
Try to test it with other numbers and see for yourself.
I tested it with the following matrix:
int[][] matrix = {
{13, 2, 17, 29},
{52, 54, 62, 73},
{140, 120, 111, 100},
{235, 245, 255, 265},
};
and used 265 and 235 as inputs, to which the output was false.
Good luck :)

Related

rotate the elements of the given array k times to the right

I have made this code to rotate an array by k times. In this when I'm adding i=0 , it is showing an "ArrayOutOfBounds" exception, and when I'm changing the value of i by 1, it is showing wrong output. Why is it showing this exception? And is there any way I could correct this code?
public void rotate(int[] nums, int k)
{ int j=0, temp=0;
for(j=0;j<k;j++)
{
for(int i=0;i<nums.length;i++)
{
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
}
}
At i=0 you are trying to access nums[i-1] = num[-1] which is an invalid position and hence an ArrayOutOfBound exception is thrown.
So, the modified version would be:
for (j=0; j<k; j++)
{
for (int i=1;i<nums.length;i++)
{
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
But the above will rotate the array by k times towards the left not right as you are shifting the elements towards the left. So, to get the right rotation you need to shift the elements from the end of the array. Like:
for (j=0; j<k; j++)
{
for (int i=nums.length-1; 0<i; i--)
{
// shifting towards the right
temp=nums[i-1];
nums[i-1]=nums[i];
nums[i]=temp;
}
}
Edit (from comments above): If i is 0, you're trying to get an index of -1 which will raise an ArrayOutOfBounds exception. If i starts from 1, then you're not dealing with the first number.
Here's the function you can use to rotate integers to the right:
public void rotate(int[] nums, int k) {
int arrLen = nums.length;
// If the number of times you want to rotate is bigger than the size of the array, get the minimum number of rotations to get the same result.
while (k > n) {
k = k - arrLen;
}
k = arrLen - k;
k = k % arrLen;
int i, m, n, temp;
int g_c_d = gcd(k, arrLen);
// Move the value in the i-th index
for (i = 0; i < g_c_d; i++) {
temp = arr[i];
m = i;
while (true) {
n = m + k;
if (n >= arrLen) {
n = n - arrLen;
}
if (n == i) {
break;
}
arr[m] = arr[n];
m = n;
}
arr[m] = temp;
}
}
// Find the greatest common divisor of two numbers, a and b
public void gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
Let me briefly explain what it does. This is one of the most known algorithms: juggling. You divide the array into the n number of sets where n denotes the greatest common divisor of the length of the array and the number of times you want to rotate. Then, you move the numbers within sets.
This might be the most efficient in terms of time (as its time complexity is O(n)).
A better solution would be taking a copy of the given array with the values '0' then looping through the given array to obtain a new_index.
Formula for the New_index for the Clock-wise rotating array:
for(int i=0;i<nums.length;i++){
int new_index = (old_index+k)%(a.length)
copy[new_index] = a[old_index]
}
Now the entire function code would be:
public static void rotate(int[] a, int k)
{
int n = a.length;
int[] copy = new int[n];
// fill the values with zeroes
for(int i=0;i<n;i++){
copy[i]=0;
}
// rotate the array
for(int i=0;i<n;i++){
int new_index = (i+k)%n;
copy[new_index] = a[i];
}
// Now that the array is copied, copy the elements to the original array. Because they asked to rotate the given array.
for(int i=0;i<n;i++){
a[i]=copy[i];
}
}
function solution(arr, k) {
if(k == 0) return arr;
if(arr.length == k) return arr;
if(arr !== undefined && arr !== null){
let counter = k > arr.length ? k % arr.length : k;
let rotArray = [];
rotArray = arr.slice(arr.length - counter, arr.length).concat(arr.slice(0,arr.length - counter))
return rotArray;
}
return arr;
}

Dynamic Programming (Codility Q: NumberSolitaire)

This is the question:
codility.com/programmers/task/number_solitaire
and below link is my result (50% from Codility):
https://codility.com/demo/results/training8AMJZH-RTA/
My code (at the first, I tried to solve this problem using Kadane's Algo):
class Solution {
public int solution(int[] A) {
int temp_max = Integer.MIN_VALUE;
int max = 0;
int k = 1;
if(A.length == 2) return A[0] + A[A.length-1];
for(int i = 1; i < A.length-1; i++) {
if(temp_max < A[i]) temp_max = A[i];
if(A[i] > 0) {
max += A[i];
temp_max = Integer.MIN_VALUE;
k = 0;
} else if(k % 6 == 0) {
max += temp_max;
temp_max = Integer.MIN_VALUE;
k = 0;
}
k++;
}
return A[0] + max + A[A.length-1];
}
And below is the solution (100% from Codility result) that I found from web:
class Solution {
public int solution(int[] A) {
int[] store = new int[A.length];
store[0] = A[0];
for (int i = 1; i < A.length; i++) {
store[i] = store[i-1];
for (int minus = 2; minus <= 6; minus++) {
if (i >= minus) {
store[i] = Math.max(store[i], store[i - minus]);
} else {
break;
}
}
store[i] += A[i];
}
return store[A.length - 1];
}
}
I have no idea what is the problem with my code:(
I tried several test cases but, nothing different with the solution & my code
but, codility test result shows mine is not perfectly correct.
(https://codility.com/demo/results/training8AMJZH-RTA/)
please anyone explain me the problem with my code~~
Try this test case[-1, -2, -3, -4, -3, -8, -5, -2, -3, -4, -5, -6, -1].
you solution return -4 (A[0],A[1],A[length-1],Here is the mistake), but the correct answer is -6 (A[0],A[6],A[length-1]).
Here is a my solution,easy to understand:
public int solution(int[] A) {
int lens = A.length;
int dp[] = new int[6];
for (int i = 0; i < 6; i++) {
dp[i] = A[0];
}
for (int i = 1; i < lens; i++) {
dp[i%6] = getMax6(dp) + A[i];
}
return dp[(lens-1)%6];
}
private int getMax6(int dp[]){
int max = dp[0];
for (int i = 1; i < dp.length; i++) {
max = Math.max(max, dp[i]);
}
return max;
}
Readable solution from Java:
public class Solution {
public static void main(String[] args) {
System.out.println(new Solution().solution(new int[]{1, -2, 0, 9, -1, -2}));
}
private int solution(int[] A) {
int N = A.length;
int[] dp = new int[N];
dp[0] = A[0];
for (int i = 1; i < N; i++) {
double sm = Double.NEGATIVE_INFINITY;
for (int j = 1; j <= 6; j++) {
if (i - j < 0) {
break;
}
double s1 = dp[i - j] + A[i];
sm = Double.max(s1, sm);
}
dp[i] = (int) sm;
}
return dp[N-1];
}
}
Here is a solution similar to #0xAliHn but using less memory. You only need to remember the last 6 moves.
def NumberSolitaire(A):
dp = [0] * 6
dp[-1] = A[0]
for i in range(1, len(A)):
maxVal = -100001
for k in range(1, 7):
if i-k >= 0:
maxVal = max(maxVal, dp[-k] + A[i])
dp.append(maxVal)
dp.pop(0)
return dp[-1]
Based on the solutions posted, I made nice readable code. Not best performance.
int[] mark = new int[A.length];
mark[0] = A[0];
IntStream.range(1, A.length)
.forEach(i -> {
int max = Integer.MIN_VALUE;
mark[i] = IntStream.rangeClosed(1, 6)
.filter(die -> i - die >= 0)
.map(r -> Math.max(mark[i - r] + A[i], max))
.max().orElse(max);
});
return mark[A.length - 1];
Because you are not using dynamic programming, you are using greedy algorithm. Your code will fail when the max number in a range will not be the right choice.
function solution(A) {
// This array contains a maximal value at any index.
const maxTill = [A[0]];
// It's a dynamic programming so we will choose maximal value at each
// Index untill we reach last index (goal)
for (let i = 1; i < A.length; i++) {
// Step 1 . max value of each index will be atleast equal to or greater than
// max value of last index.
maxTill[i] = maxTill[i - 1];
// For each index we are finding the max of last 6 array value
// And storing it into Max value.
for (let dice = 1; dice <= 6; dice++) {
// If array index is itself less than backtrack index
// break as you dont have 6 boxes in your left
if (dice > i) {
break;
} else {
// The most important line .
// Basically checking the max of last 6 boxes using a loop.
maxTill[i] = Math.max(
maxTill[i - dice],
maxTill[i]
);
}
}
// Until this point maxStill contains the maximal value
// to reach to that index.
// To end the game we need to touch that index as well, so
// add the value of the index as well.
maxTill[i] += A[i];
}
return maxTill[A.length - 1];
}
console.log(solution([-1, -2, -3, -4, -3, -8, -5, -2, -3, -4, -5, -6, -1]));
This is my solution. I try to make the code easy to apprehend. It might not save space as much as it can.
private static int solution(int A[])
{
// N // N is an integer within the range [2..100,000];
// A[] // each element of array A is an integer within the range [−10,000..10,000].
int N = A.length;
int[] bestResult = new int[N]; // record the current bestResult
Arrays.fill(bestResult, Integer.MIN_VALUE); // fill in with the smallest integer value
// initialize
bestResult[0] = A[0];
for (int i = 0;i < A.length;i++) {
// calculate six possible results every round
for (int j = i + 1; (j < A.length) && (i < A.length) && j < (i + 1) + 6; j++) {
// compare
int preMaxResult = bestResult[j]; // the max number so far
int nowMaxResult = bestResult[i] + A[j]; // the max number at bestResult[i] + A[j]
bestResult[j] = Math.max(preMaxResult, nowMaxResult);
}
}
return bestResult[bestResult.length-1];
}
Here is the simple Python 3 solution:
import sys
def solution(A):
dp = [0] * len(A)
dp[0] = A[0]
for i in range(1, len(A)):
maxVal = -sys.maxsize - 1
for k in range(1, 7):
if i-k >= 0:
maxVal = max(maxVal, dp[i-k] + A[i])
dp[i] = maxVal
return dp[len(A)-1]
100% c++ solution(
results)
#include <climits>
int solution(vector<int>& A) {
const int N = A.size();
if (N == 2)
return A[0] + A[1];
vector<int> MaxSum(N, INT_MIN);
MaxSum[0] = A[0];
for (int i = 1; i < N; i++) {
for (int dice = 1; dice <= 6; dice++) {
if (dice > i)
break;
MaxSum[i] = max(MaxSum[i], A[i] + MaxSum[i - dice]);
}
}
return MaxSum[N-1];
}
100% python solution
with the help of the answers above and https://sapy.medium.com/cracking-the-coding-interview-30eb419c4c57
def solution(A):
# write your code in Python 3.6
# initialize maxUntil [0]*n
n = len(A)
maxUntil = [0 for i in range(n)]
maxUntil[0]=A[0]
# fill in maxUntil, remember to chack limits
for i in range(1, n): # for each
maxUntil[i] = maxUntil [i-1]
# check the max 6 to the left:
# for 1,..,6:
for dice in range(1,7):
if dice > i: # if dice bigger than loc - we are out of range
break
#else: check if bigger than cur elem, if so - update elem
maxUntil[i] = max(maxUntil[i],maxUntil[i-dice])
# add the current jump:
maxUntil[i] +=A[i]
# must reach the last sq:
return maxUntil[n-1]
I would like to explain the algorithm I have come up with and then show you the implementation in C++.
Create a hash for the max sums. We only need to store the elements within reach, so the last 6 elements. This is because the dice can only go back so much.
Initialise the hash with the first element in the array for simplicity since the first element in this hash equals to the first element of the inputs.
Then go through the input elements from the second element.
For each iteration, find the maximum values from the last 6 indices. Add the current value to that to get the current max sum.
When we reach the end of the inputs, exit the loop.
Return the max sum of the last element calculated. For this, we need clipping with module due to the space optimisation
The runtime complexity of this dynamic programming solution is O(N) since we go through element in the inputs. If we consider the dice range K, then this would be O(N * K).
The space complexity is O(1) because we have a hash for the last six elements. It is O(K) if we does not consider the number of dice faces constant, but K.
int solution(vector<int> &A)
{
vector<int> max_sums(6, A[0]);
for (size_t i = 1; i < A.size(); ++i) max_sums[i % max_sums.size()] = *max_element(max_sums.cbegin(), max_sums.cend()) + A[i];
return max_sums[(A.size() - 1) % max_sums.size()];
}
Here's my answer which gives 100% for Kotlin
val pr = IntArray(A.size) { Int.MIN_VALUE }
pr[0] = A.first()
for ((index, value) in pr.withIndex()) {
for (i in index + 1..min(index + 6, A.lastIndex)) {
pr[i] = max(value + A[i], pr[i])
}
}
return pr.last()
I used forwarded prediction, where I fill the next 6 items of the max value the current index can give.

Largest 5 in array of 10 numbers without sorting

Here's my code to find the max number in an array of numbers, but i can't seem to understand how to get the top 5 numbers and store them in an array and later retrieve them
Here's the code:
public class Max {
public static void main (String[] args)
{
int i;
int large[]=new int[5];
int array[] = {33,55,13,46,87,42,10,34,43,56};
int max = array[0]; // Assume array[0] to be the max for time-being
//Looping n-1 times, O(n)
for( i = 1; i < array.length; i++) // Iterate through the First Index and compare with max
{
// O(1)
if( max < array[i])
{
// O(1)
max = array[i];// Change max if condition is True
large[i] = max;
}
}
for (int j = 0; j<5; j++)
{
System.out.println("Largest 5 : "+large[j]);
}
System.out.println("Largest is: "+ max);
// Time complexity being: O(n) * [O(1) + O(1)] = O(n)
}
}
I'm using an array to store 5 numbers, but when i run it, it is not what i want.
Can anyone help me with the program?
The optimum data structure to retrieve top n items from a larger collection is the min/max heap and the related abstract data structure is called the priority queue. Java has an unbounded PriorityQueue which is based on the heap structure, but there is no version specialized for primitive types. It can used as a bounded queue by adding external logic, see this comment for details..
Apache Lucene has an implementation of the bounded priority queue:
http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-core/5.2.0/org/apache/lucene/util/PriorityQueue.java#PriorityQueue
Here is a simple modification that specializes it for ints:
/*
* Original work Copyright 2014 The Apache Software Foundation
* Modified work Copyright 2015 Marko Topolnik
*
* Licensed under the Apache License, Version 2.0 (the "License");
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** A PriorityQueue maintains a partial ordering of its elements such that the
* worst element can always be found in constant time. Put()'s and pop()'s
* require log(size) time.
*/
class IntPriorityQueue {
private static int NO_ELEMENT = Integer.MIN_VALUE;
private int size;
private final int maxSize;
private final int[] heap;
IntPriorityQueue(int maxSize) {
this.heap = new int[maxSize == 0 ? 2 : maxSize + 1];
this.maxSize = maxSize;
}
private static boolean betterThan(int left, int right) {
return left > right;
}
/**
* Adds an int to a PriorityQueue in log(size) time.
* It returns the object (if any) that was
* dropped off the heap because it was full. This can be
* the given parameter (in case it isn't better than the
* full heap's minimum, and couldn't be added), or another
* object that was previously the worst value in the
* heap and now has been replaced by a better one, or null
* if the queue wasn't yet full with maxSize elements.
*/
public void consider(int element) {
if (size < maxSize) {
size++;
heap[size] = element;
upHeap();
} else if (size > 0 && betterThan(element, heap[1])) {
heap[1] = element;
downHeap();
}
}
public int head() {
return size > 0 ? heap[1] : NO_ELEMENT;
}
/** Removes and returns the least element of the PriorityQueue in log(size)
time. */
public int pop() {
if (size > 0) {
int result = heap[1];
heap[1] = heap[size];
size--;
downHeap();
return result;
} else {
return NO_ELEMENT;
}
}
public int size() {
return size;
}
public void clear() {
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
private void upHeap() {
int i = size;
// save bottom node
int node = heap[i];
int j = i >>> 1;
while (j > 0 && betterThan(heap[j], node)) {
// shift parents down
heap[i] = heap[j];
i = j;
j >>>= 1;
}
// install saved node
heap[i] = node;
}
private void downHeap() {
int i = 1;
// save top node
int node = heap[i];
// find worse child
int j = i << 1;
int k = j + 1;
if (k <= size && betterThan(heap[j], heap[k])) {
j = k;
}
while (j <= size && betterThan(node, heap[j])) {
// shift up child
heap[i] = heap[j];
i = j;
j = i << 1;
k = j + 1;
if (k <= size && betterThan(heap[j], heap[k])) {
j = k;
}
}
// install saved node
heap[i] = node;
}
}
The way you implement betterThan decides whether it will behave as a min or max heap. This is how it's used:
public int[] maxN(int[] input, int n) {
final int[] output = new int[n];
final IntPriorityQueue q = new IntPriorityQueue(output.length);
for (int i : input) {
q.consider(i);
}
// Extract items from heap in sort order
for (int i = output.length - 1; i >= 0; i--) {
output[i] = q.pop();
}
return output;
}
Some interest was expressed in the performance of this approach vs. the simple linear scan from user rakeb.void. These are the results, size pertaining to the input size, always looking for 16 top elements:
Benchmark (size) Mode Cnt Score Error Units
MeasureMinMax.heap 32 avgt 5 270.056 ± 37.948 ns/op
MeasureMinMax.heap 64 avgt 5 379.832 ± 44.703 ns/op
MeasureMinMax.heap 128 avgt 5 543.522 ± 52.970 ns/op
MeasureMinMax.heap 4096 avgt 5 4548.352 ± 208.768 ns/op
MeasureMinMax.linear 32 avgt 5 188.711 ± 27.085 ns/op
MeasureMinMax.linear 64 avgt 5 333.586 ± 18.955 ns/op
MeasureMinMax.linear 128 avgt 5 677.692 ± 163.470 ns/op
MeasureMinMax.linear 4096 avgt 5 18290.981 ± 5783.255 ns/op
Conclusion: constant factors working against the heap approach are quite low. The breakeven point is around 70-80 input elements and from then on the simple approach loses steeply. Note that the constant factor stems from the final operation of extracting items in sort order. If this is not needed (i.e., just a set of the best items is enough), the we can simply retrieve the internal heap array directly and ignore the heap[0] element which is not used by the algorithm. In that case this solution beats one like rakib.void's even for the smallest input size (I tested with 4 top elements out of 32).
Look at the following code:
public static void main(String args[]) {
int i;
int large[] = new int[5];
int array[] = { 33, 55, 13, 46, 87, 42, 10, 34, 43, 56 };
int max = 0, index;
for (int j = 0; j < 5; j++) {
max = array[0];
index = 0;
for (i = 1; i < array.length; i++) {
if (max < array[i]) {
max = array[i];
index = i;
}
}
large[j] = max;
array[index] = Integer.MIN_VALUE;
System.out.println("Largest " + j + " : " + large[j]);
}
}
Note: If you don't want to change the inputted array, then make a copy of it and do the same operation on the copied array.
Take a look at Integer.MIN_VALUE.
I get the following output:
Largest 0 : 87
Largest 1 : 56
Largest 2 : 55
Largest 3 : 46
Largest 4 : 43
Here is a simple solution i quickly knocked up
public class Main {
public static void main(String args[]) {
int i;
int large[] = new int[5];
int array[] = { 33, 55, 13, 46, 87, 42, 10, 34, 43, 56 };
for (int j = 0; j < array.length; j++) {
for (i = 4; i >= 0; i--) {
if (array[j] > large[i]) {
if (i == 4) {
large[i] = array[j];
}
else{
int temp = large[i];
large[i] = array[j];
large[i+1] = temp;
}
}
}
}
for (int j = 0; j<5; j++)
{
System.out.println("Largest "+ j + ":"+ large[j]);
}
}
}
Sorting, regular expressions, complex data structures are fine and make programming easy. However, I constantly see them misused nowadays and no one has to wonder:
Even if computers have become thousands of times faster over the past decades, the perceived performance still continues to not only not grow, but actually slows down. Once in your terminal application, you had instant feedback, even in Windows 3.11 or Windows 98 or Gnome 1, you often had instant feedback from your machine.
But it seems that it becomes increasingly popular to not only crack nuts with a sledgehammer, but even corns of wheat with steam hammers.
You don't need no friggin' sorting or complex datastructures for such a small problem. Don't let me invoke Z̴̲̝̻̹̣̥͎̀A̞̭̞̩̠̝̲͢L̛̤̥̲͟͜G͘҉̯̯̼̺O̦͈͙̗͎͇̳̞̕͡. I cannot take it, and even if I don't have a Java compiler at hands, here's my take in C++ (but will work in Java, too).
Basically, it initializes your 5 maxima to the lowest possible integer values. Then, it goes through your list of numbers, and for each number, it looks up into your maxima to see if it has a place there.
#include <vector>
#include <limits> // for integer minimum
#include <iostream> // for cout
using namespace std; // not my style, I just do so to increase readability
int main () {
// basically, an array of length 5, initialized to the minimum integer
vector<int> maxima(5, numeric_limits<int>::lowest());
// your numbers
vector<int> numbers = {33, 55, 13, 46, 87, 42, 10, 34, 43, 56};
// go through all numbers.
for(auto n : numbers) {
// find smallest in maxima.
auto smallestIndex = 0;
for (auto m=0; m!=maxima.size(); ++m) {
if (maxima[m] < maxima[smallestIndex]) {
smallestIndex = m;
}
}
// check if smallest is smaller than current number
if (maxima[smallestIndex] < n)
maxima[smallestIndex] = n;
}
cout << "maximum values:\n";
for(auto m : maxima) {
cout << " - " << m << '\n';
}
}
It is a similar solution to rakeb.voids' answer, but flips the loops inside out and does not have to modify the input array.
Use steam hammers when appropriate only. Learn algorithms and datastructures. And know when NOT TO USE YOUR KUNG-FU. Otherwise, you are guilty of increasing the society's waste unecessarily and contribute to overall crapness.
(Java translation by Marko, signature adapted to zero allocation)
static int[] phresnel(int[] input, int[] output) {
Arrays.fill(output, Integer.MIN_VALUE);
for (int in : input) {
int indexWithMin = 0;
for (int i = 0; i < output.length; i++) {
if (output[i] < output[indexWithMin]) {
indexWithMin = i;
}
}
if (output[indexWithMin] < in) {
output[indexWithMin] = in;
}
}
Arrays.sort(output);
return output;
}
As an alternative to sorting, here is the logic. You figure out the code.
Keep a list (or array) of the top X values found so far. Will of course start out empty.
For each new value (iteration), check against top X list.
If top X list is shorter than X, add value.
If top X list is full, check if new value is greater than any value. If it is, remove smallest value from top X list and add new value.
Hint: Code will be better if top X list is sorted.
If you don't want to sort you can check lower number and it's position and replace. WORKING DEMO HERE.
public static void main(String[] args) {
int array[] = {33,55,13,46,87,42,10,34,43,56};
int mArray[] = new int[5];
int j = 0;
for(int i = 0; i < array.length; i++) {
if (array[i] > lower(mArray)) {
mArray[lowerPos(mArray)] = array[i];
}
}
System.out.println(Arrays.toString(mArray));
}
public static int lower(int[] array) {
int lower = Integer.MAX_VALUE;
for (int n : array) {
if (n < lower)
lower = n;
}
return lower;
}
public static int lowerPos(int[] array) {
int lower = Integer.MAX_VALUE;
int lowerPos = 0;
for (int n = 0; n < array.length; n++) {
if (array[n] < lower) {
lowerPos = n;
lower = array[n];
}
}
return lowerPos;
}
OUTPUT:
[43, 55, 56, 46, 87]
try :
public static int getMax(int max,int[] arr ){
int pos=0;
//Looping n-1 times, O(n)
for( int i = 0; i < arr.length; i++) // Iterate through the First Index and compare with max
{
// O(1)
if( max < arr[i])
{
// O(1)
max = arr[i];// Change max if condition is True
pos=i;
}
}
arr[pos]=0;
return max;
}
public static void main(String[] args) {
int large[]=new int[10];
int array[] = {33,55,13,46,87,42,10,34,43,56};
int k=0;
for(int i=0;i<array.length;i++){
large[k++]=getMax(0,array);
}
System.out.println("Largest 5 is: "+ Arrays.toString(Arrays.copyOf(large,5)));
}
output:
Largest 5 is: [87, 56, 55, 46, 43]
Here is another approach:
public static void main(String args[]){
int i;
int largestSize = 4;
int array[] = {33,55,13,46,87,42,10,34};
// copy first 4 elemets, they can just be the highest
int large[]= Arrays.copyOf(array, largestSize);
// get the smallest value of the large array before the first start
int smallest = large[0];
int smallestIndex = 0;
for (int j = 1;j<large.length;++j) {
if (smallest > large[j]) {
smallest = large[j];
smallestIndex = j;
}
}
// First Loop start one elemnt after the copy
for(i = large.length; i < array.length; i++)
{
// get the smallest value and index of the large array
if(smallest < array[i])
{
large[smallestIndex] = array[i];
// check the next smallest value
smallest = large[0];
smallestIndex = 0;
for (int j = 1;j<large.length;++j) {
if (smallest > large[j]) {
smallest = large[j];
smallestIndex = j;
}
}
}
}
for (int j = 0; j<large.length; j++)
{
System.out.println("Largest 5 : "+large[j]);
}
System.out.println();
System.out.println("Largest is: "+ getHighest(large));
}
private static int getHighest(int[] array) {
int highest = array[0];
for (int i = 1;i<array.length;++i) {
if (highest < array[i]) {
highest = array[i];
}
}
return highest;
}
First of all, you can't use the i constant with large array. i goes up to 10, while large length is 5.
Use a separate variable for that and increment when you add a new value.
Second, this logic is not retrieving the max values, you need to go over your array fully, retrieve the max value and add it to your array. Then you have to it again. You can write a first loop which use large.length as a condition and the inner loop which will use array.length. Or, you can use recursion.
You could do this properly in an OOp way. This maintains a list of the n largest values of a list of offered values.
class Largest<T extends Comparable<T>> {
// Largest so far - null if we haven't yet seen that many.
List<T> largest;
public Largest(int n) {
// Build my list.
largest = new ArrayList(n);
// Clear it.
for (int i = 0; i < n; i++) {
largest.add(i, null);
}
}
public void offer(T next) {
// Where to put it - or -1 if nowhere.
int place = -1;
// Must replace only the smallest replaceable one.
T smallest = null;
for (int i = 0; i < largest.size(); i++) {
// What's there?
T l = largest.get(i);
if (l == null) {
// Always replace null.
place = i;
break;
}
if (l.compareTo(next) < 0) {
// Only replace the smallest.
if (smallest == null || l.compareTo(smallest) < 0) {
// Remember here but keep looking in case there is a null or a smaller.
smallest = l;
place = i;
}
}
}
if (place != -1) {
// Replace it.
largest.set(place, next);
}
}
public List<T> get() {
return largest;
}
}
public void test() {
Integer array[] = {33, 55, 13, 46, 87, 42, 10, 34, 43, 56};
Largest<Integer> l = new Largest<>(5);
for (int i : array) {
l.offer(i);
}
List<Integer> largest = l.get();
Collections.sort(largest);
System.out.println(largest);
// Check it.
List<Integer> asList = Arrays.asList(array);
Collections.sort(asList);
asList = asList.subList(asList.size() - largest.size(), asList.size());
System.out.println(asList);
}
For larger numbers you can improve the algorithm using binarySearch to find the best place to put the new item instead of blindly walking the whole list. This has the added benefit of returning a sorted list.
class Largest<T extends Comparable<T>> {
// Largest so far - null if we haven't yet seen that many.
List<T> largest;
// Limit.
final int n;
public Largest(int n) {
// Build my list.
largest = new ArrayList(n + 1);
this.n = n;
}
public void offer(T next) {
// Try to find it in the list.
int where = Collections.binarySearch(largest, next, Collections.reverseOrder());
// Positive means found.
if (where < 0) {
// -1 means at start.
int place = -where - 1;
// Discard anything beyond n.
if (place < n) {
// Insert here.
largest.add(place, next);
// Trim if necessary.
if (largest.size() > n) {
largest.remove(n);
}
}
}
}
public List<T> get() {
return largest;
}
}
Simple working solution for this for all condition is as given below. Please refer code below and let me know in case of any issue in comments.
public static void main(String[] args) {
int arr[] = {75, 4, 2, 43, 56, 1,66};
int k = 5;
int result = find5thMaxValueApproach3(arr, k);
System.out.println("\n 5th largest element is : " + result);
}
static int find5thMaxValueApproach3(int arr[], int k){
int newMax = 0;
int len = arr.length;
int lastMax = Integer.MAX_VALUE;
for(int j = 0; j < k; j++){
int i = 0;
while(arr[i] >= lastMax )
i++;
if(i >= len)
break;
newMax = arr[i];
for( ; i < len; i++){
if( arr[i] < lastMax && arr[i] > newMax){
newMax = arr[i];
}
}
System.out.println("newMax =" + newMax+ " lastMax="+ lastMax);
lastMax = newMax;
}
return lastMax;
}

Programming Test - Codility - Dominator [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I just had a codility problem give me a hard time and I'm still trying to figure out how the space and time complexity constraints could have been met.
The problem is as follows:
A dominant member in the array is one that occupies over half the positions in the array, for example:
{3, 67, 23, 67, 67}
67 is a dominant member because it appears in the array in 3/5 (>50%) positions.
Now, you are expected to provide a method that takes in an array and returns an index of the dominant member if one exists and -1 if there is none.
Easy, right? Well, I could have solved the problem handily if it were not for the following constraints:
Expected time complexity is O(n)
Expected space complexity is O(1)
I can see how you could solve this for O(n) time with O(n) space complexities as well as O(n^2) time with O(1) space complexities, but not one that meets both O(n) time and O(1) space.
I would really appreciate seeing a solution to this problem. Don't worry, the deadline has passed a few hours ago (I only had 30 minutes), so I'm not trying to cheat. Thanks.
Googled "computing dominant member of array", it was the first result. See the algorithm described on page 3.
element x;
int count ← 0;
For(i = 0 to n − 1) {
if(count == 0) { x ← A[i]; count++; }
else if (A[i] == x) count++;
else count−−;
}
Check if x is dominant element by scanning array A
Basically observe that if you find two different elements in the array, you can remove them both without changing the dominant element on the remainder. This code just keeps tossing out pairs of different elements, keeping track of the number of times it has seen the single remaining unpaired element.
Find the median with BFPRT, aka median of medians (O(N) time, O(1) space). Then scan through the array -- if one number dominates, the median will be equal to that number. Walk through the array and count the number of instances of that number. If it's over half the array, it's the dominator. Otherwise, there is no dominator.
Adding a Java 100/100 O(N) time with O(1) space:
https://codility.com/demo/results/demoPNG8BT-KEH/
class Solution {
public int solution(int[] A) {
int indexOfCandidate = -1;
int stackCounter = 0, candidate=-1, value=-1, i =0;
for(int element: A ) {
if (stackCounter == 0) {
value = element;
++stackCounter;
indexOfCandidate = i;
} else {
if (value == element) {
++stackCounter;
} else {
--stackCounter;
}
}
++i;
}
if (stackCounter > 0 ) {
candidate = value;
} else {
return -1;
}
int countRepetitions = 0;
for (int element: A) {
if( element == candidate) {
++countRepetitions;
}
if(countRepetitions > (A.length / 2)) {
return indexOfCandidate;
}
}
return -1;
}
}
If you want to see the Java source code it's here, I added some test cases as comments as the beginning of the file.
Java solution with score 100%
public int solution(int[] array) {
int candidate=0;
int counter = 0;
// Find candidate for leader
for(int i=0; i<array.length; i++){
if(counter == 0) candidate = i;
if(array[i] == array[candidate]){
counter++;
}else {
counter--;
}
}
// Count candidate occurrences in array
counter = 0;
for(int i=0; i<array.length; i++){
if(array[i] == array[candidate]) counter++;
}
// Check that candidate occurs more than array.lenght/2
return counter>array.length/2 ? candidate : -1;
}
In python, we are lucky some smart people have bothered to implement efficient helpers using C and shipped it in the standard library. The collections.Counter is useful here.
>>> data = [3, 67, 23, 67, 67]
>>> from collections import Counter
>>> counter = Counter(data) # counter accepts any sequence/iterable
>>> counter # dict like object, where values are the occurrence
Counter({67: 3, 3: 1, 23: 1})
>>> common = counter.most_common()[0]
>>> common
(67, 3)
>>> common[0] if common[1] > len(data) / 2.0 + 1 else -1
67
>>>
If you prefer a function here is one ...
>>> def dominator(seq):
counter = Counter(seq)
common = counter.most_common()[0]
return common[0] if common[1] > len(seq) / 2.0 + 1 else -1
...
>>> dominator([1, 3, 6, 7, 6, 8, 6])
-1
>>> dominator([1, 3, 6, 7, 6, 8, 6, 6])
6
This question looks hard if a small trick does not come to the mind :). I found this trick in this document of codility : https://codility.com/media/train/6-Leader.pdf.
The linear solution is explained at the bottom of this document.
I implemented the following java program which gave me a score of 100 on the same lines.
public int solution(int[] A) {
Stack<Integer> stack = new Stack<Integer>();
for (int i =0; i < A.length; i++)
{
if (stack.empty())
stack.push(new Integer(A[i]));
else
{
int topElem = stack.peek().intValue();
if (topElem == A[i])
{
stack.push(new Integer(A[i]));
}
else
{
stack.pop();
}
}
}
if (stack.empty())
return -1;
int elem = stack.peek().intValue();
int count = 0;
int index = 0;
for (int i = 0; i < A.length; i++)
{
if (elem == A[i])
{
count++;
index = i;
}
}
if (count > ((double)A.length/2.0))
return index;
else
return -1;
}
Here's my C solution which scores 100%
int solution(int A[], int N) {
int candidate;
int count = 0;
int i;
// 1. Find most likely candidate for the leader
for(i = 0; i < N; i++){
// change candidate when count reaches 0
if(count == 0) candidate = i;
// count occurrences of candidate
if(A[i] == A[candidate]) count++;
else count--;
}
// 2. Verify that candidate occurs more than N/2 times
count = 0;
for(i = 0; i < N; i++) if(A[i] == A[candidate]) count++;
if (count <= N/2) return -1;
return candidate; // return index of leader
}
100%
import java.util.HashMap;
import java.util.Map;
class Solution {
public static int solution(int[] A) {
final int N = A.length;
Map<Integer, Integer> mapOfOccur = new HashMap((N/2)+1);
for(int i=0; i<N; i++){
Integer count = mapOfOccur.get(A[i]);
if(count == null){
count = 1;
mapOfOccur.put(A[i],count);
}else{
mapOfOccur.replace(A[i], count, ++count);
}
if(count > N/2)
return i;
}
return -1;
}
}
Does it have to be a particularly good algorithm? ;-)
static int dominant(final int... set) {
final int[] freqs = new int[Integer.MAX_VALUE];
for (int n : set) {
++freqs[n];
}
int dom_freq = Integer.MIN_VALUE;
int dom_idx = -1;
int dom_n = -1;
for (int i = set.length - 1; i >= 0; --i) {
final int n = set[i];
if (dom_n != n) {
final int freq = freqs[n];
if (freq > dom_freq) {
dom_freq = freq;
dom_n = n;
dom_idx = i;
} else if (freq == dom_freq) {
dom_idx = -1;
}
}
}
return dom_idx;
}
(this was primarily meant to poke fun at the requirements)
Consider this 100/100 solution in Ruby:
# Algorithm, as described in https://codility.com/media/train/6-Leader.pdf:
#
# * Iterate once to find a candidate for dominator.
# * Count number of candidate occurences for the final conclusion.
def solution(ar)
n_occu = 0
candidate = index = nil
ar.each_with_index do |elem, i|
if n_occu < 1
# Here comes a new dominator candidate.
candidate = elem
index = i
n_occu += 1
else
if candidate == elem
n_occu += 1
else
n_occu -= 1
end
end # if n_occu < 1
end
# Method result. -1 if no dominator.
# Count number of occurences to check if candidate is really a dominator.
if n_occu > 0 and ar.count {|_| _ == candidate} > ar.size/2
index
else
-1
end
end
#--------------------------------------- Tests
def test
sets = []
sets << ["4666688", [1, 2, 3, 4], [4, 6, 6, 6, 6, 8, 8]]
sets << ["333311", [0, 1, 2, 3], [3, 3, 3, 3, 1, 1]]
sets << ["313131", [-1], [3, 1, 3, 1, 3, 1]]
sets << ["113333", [2, 3, 4, 5], [1, 1, 3, 3, 3, 3]]
sets.each do |name, one_of_expected, ar|
out = solution(ar)
raise "FAILURE at test #{name.inspect}: #{out.inspect} not in #{expected.inspect}" if not one_of_expected.include? out
end
puts "SUCCESS: All tests passed"
end
Here is an easy to read, 100% score version in Objective-c
if (A.count > 100000)
return -1;
NSInteger occur = 0;
NSNumber *candidate = nil;
for (NSNumber *element in A){
if (!candidate){
candidate = element;
occur = 1;
continue;
}
if ([candidate isEqualToNumber:element]){
occur++;
}else{
if (occur == 1){
candidate = element;
continue;
}else{
occur--;
}
}
}
if (candidate){
occur = 0;
for (NSNumber *element in A){
if ([candidate isEqualToNumber:element])
occur++;
}
if (occur > A.count / 2)
return [A indexOfObject:candidate];
}
return -1;
100% score JavaScript solution. Technically it's O(nlogn) but still passed.
function solution(A) {
if (A.length == 0)
return -1;
var S = A.slice(0).sort(function(a, b) {
return a - b;
});
var domThresh = A.length/2;
var c = S[Math.floor(domThresh)];
var domCount = 0;
for (var i = 0; i < A.length; i++) {
if (A[i] == c)
domCount++;
if (domCount > domThresh)
return i;
}
return -1;
}
This is the solution in VB.NET with 100% performance.
Dim result As Integer = 0
Dim i, ladderVal, LadderCount, size, valCount As Integer
ladderVal = 0
LadderCount = 0
size = A.Length
If size > 0 Then
For i = 1 To size - 1
If LadderCount = 0 Then
LadderCount += 1
ladderVal = A(i)
Else
If A(i) = ladderVal Then
LadderCount += 1
Else
LadderCount -= 1
End If
End If
Next
valCount = 0
For i = 0 To size - 1
If A(i) = ladderVal Then
valCount += 1
End If
Next
If valCount <= size / 2 Then
result = 0
Else
LadderCount = 0
For i = 0 To size - 1
If A(i) = ladderVal Then
valCount -= 1
LadderCount += 1
End If
If LadderCount > (LadderCount + 1) / 2 And (valCount > (size - (i + 1)) / 2) Then
result += 1
End If
Next
End If
End If
Return result
See the correctness and performance of the code
Below solution resolves in complexity O(N).
public int solution(int A[]){
int dominatorValue=-1;
if(A != null && A.length>0){
Hashtable<Integer, Integer> count=new Hashtable<>();
dominatorValue=A[0];
int big=0;
for (int i = 0; i < A.length; i++) {
int value=0;
try{
value=count.get(A[i]);
value++;
}catch(Exception e){
}
count.put(A[i], value);
if(value>big){
big=value;
dominatorValue=A[i];
}
}
}
return dominatorValue;
}
100% in PHP https://codility.com/demo/results/trainingVRQGQ9-NJP/
function solution($A){
if (empty($A)) return -1;
$copy = array_count_values($A); // 3 => 7, value => number of repetition
$max_repetition = max($copy); // at least 1 because the array is not empty
$dominator = array_search($max_repetition, $copy);
if ($max_repetition > count($A) / 2) return array_search($dominator, $A); else return -1;
}
i test my code its work fine in arrays lengths between 2 to 9
public static int sol (int []a)
{
int count = 0 ;
int candidateIndex = -1;
for (int i = 0; i <a.length ; i++)
{
int nextIndex = 0;
int nextOfNextIndex = 0;
if(i<a.length-2)
{
nextIndex = i+1;
nextOfNextIndex = i+2;
}
if(count==0)
{
candidateIndex = i;
}
if(a[candidateIndex]== a[nextIndex])
{
count++;
}
if (a[candidateIndex]==a[nextOfNextIndex])
{
count++;
}
}
count -- ;
return count>a.length/2?candidateIndex:-1;
}
Adding a Java 100/100 O(N) time with O(1) space:
// you can also use imports, for example:
import java.util.Stack;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
int count = 0;
Stack<Integer> integerStack = new Stack<Integer>();
for (int i = 0; i < A.length; i++) {
if (integerStack.isEmpty()) {
integerStack.push(A[i]);
} else if (integerStack.size() > 0) {
if (integerStack.peek() == A[i])
integerStack.push(A[i]);
else
integerStack.pop();
}
}
if (!integerStack.isEmpty()) {
for (int i = 0; i < integerStack.size(); i++) {
for (int j = 0; j < A.length; j++) {
if (integerStack.get(i) == A[j])
count++;
if (count > A.length / 2)
return j;
}
count = 0;
}
}
return -1;
}
}
Here is test result from codility.
I think this question has already been resolved somewhere. The "official" solution should be :
public int dominator(int[] A) {
int N = A.length;
for(int i = 0; i< N/2+1; i++)
{
int count=1;
for(int j = i+1; j < N; j++)
{
if (A[i]==A[j]) {count++; if (count > (N/2)) return i;}
}
}
return -1;
}
How about sorting the array first? You then compare middle and first and last elements of the sorted array to find the dominant element.
public Integer findDominator(int[] arr) {
int[] arrCopy = arr.clone();
Arrays.sort(arrCopy);
int length = arrCopy.length;
int middleIndx = (length - 1) /2;
int middleIdxRight;
int middleIdxLeft = middleIndx;
if (length % 2 == 0) {
middleIdxRight = middleIndx+1;
} else {
middleIdxRight = middleIndx;
}
if (arrCopy[0] == arrCopy[middleIdxRight]) {
return arrCopy[0];
}
if (arrCopy[middleIdxLeft] == arrCopy[length -1]) {
return arrCopy[middleIdxLeft];
}
return null;
}
C#
int dominant = 0;
int repeat = 0;
int? repeatedNr = null;
int maxLenght = A.Length;
int halfLenght = A.Length / 2;
int[] repeations = new int[A.Length];
for (int i = 0; i < A.Length; i++)
{
repeatedNr = A[i];
for (int j = 0; j < A.Length; j++)
{
if (repeatedNr == A[j])
{
repeations[i]++;
}
}
}
repeatedNr = null;
for (int i = 0; i < repeations.Length; i++)
{
if (repeations[i] > repeat)
{
repeat = repeations[i];
repeatedNr = A[i];
}
}
if (repeat > halfLenght)
dominant = int.Parse(repeatedNr.ToString());
class Program
{
static void Main(string[] args)
{
int []A= new int[] {3,6,2,6};
int[] B = new int[A.Length];
Program obj = new Program();
obj.ABC(A,B);
}
public int ABC(int []A, int []B)
{
int i,j;
int n= A.Length;
for (j=0; j<n ;j++)
{
int count = 1;
for (i = 0; i < n; i++)
{
if ((A[j]== A[i] && i!=j))
{
count++;
}
}
int finalCount = count;
B[j] = finalCount;// to store the no of times a number is repeated
}
// int finalCount = count / 2;
int finalCount1 = B.Max();// see which number occurred max times
if (finalCount1 > (n / 2))
{ Console.WriteLine(finalCount1); Console.ReadLine(); }
else
{ Console.WriteLine("no number found"); Console.ReadLine(); }
return -1;
}
}
In Ruby you can do something like
def dominant(a)
hash = {}
0.upto(a.length) do |index|
element = a[index]
hash[element] = (hash[element] ? hash[element] + 1 : 1)
end
res = hash.find{|k,v| v > a.length / 2}.first rescue nil
res ||= -1
return res
end
#Keith Randall solution is not working for {1,1,2,2,3,2,2}
his solution was:
element x;
int count ← 0;
For(i = 0 to n − 1) {
if(count == 0) { x ← A[i]; count++; }
else if (A[i] == x) count++;
else count−−;
}
Check if x is dominant element by scanning array A
I converted it into java as below:
int x = 0;
int count = 0;
for(int i = 0; i < (arr.length - 1); i++) {
if(count == 0) {
x = arr[i];
count++;
}
else if (arr[i] == x)
count++;
else count--;
}
return x;
Out put : 3
Expected: 2
This is my answer in Java: I store a count in seperate array which counts duplicates of each of the entries of the input array and then keeps a pointer to the array position that has the most duplicates. This is the dominator.
private static void dom(int[] a) {
int position = 0;
int max = 0;
int score = 0;
int counter = 0;
int[]result = new int[a.length];
for(int i = 0; i < a.length; i++){
score = 0;
for(int c = 0; c < a.length;c++){
if(a[i] == a[c] && c != i ){
score = score + 1;
result[i] = score;
if(result[i] > position){
position = i;
}
}
}
}
//This is just to facilitate the print function and MAX = the number of times that dominator number was found in the list.
for(int x = 0 ; x < result.length-1; x++){
if(result[x] > max){
max = result[x] + 1;
}
}
System.out.println(" The following number is the dominator " + a[position] + " it appears a total of " + max);
}

printing arrngements

How can I do arrangements. of numbers... such that each new number formed out of arrangement has at max a difference of 1 from prev maxima.
e.g.
if input is k=1 output will be 1
if k =2 outputs are : 11, 12
2,1 is wrong as left most has to be 1 always.
if k = 3 outputs are: 111,112, 121, 122, 123
if k = 4 : 1111,1112,1121,1122,1123,1212,1211,1213,1223,1221, 1222, 1233, 1234
1423 is wrong diff b/w 1 and 4 is 3.
1243 is wrong diff b/w 2 and 4 is 2....
How I do this using DP, if possible?
This is one of the solution for above question... can anyone help me to understand this code...
Thanks in advance...
public class MaxOneDiff {
public static void main(String[] args) {
int k = 4;
getList(k);
}
public static void getList(int k) {
int arr[] = new int[k];
int index = 0;
printRecList(k, arr, index, k);
}
public static void printRecList(int k, int arr[], int index, int range) {
if (k == 0) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
} else {
for (int i = 1; i <= range; i++) {
if (index == 0) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
} else {
int t = arr[index-1]-i;
t = t > 0 ? t : -t;
if (t < 2) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
}
}
}
}
}
}
Let's start with the easy part:
public static void getList(int k) {
int arr[] = new int[k];
int index = 0;
printRecList(k, arr, index, k);
}
This is a helper to the Print Recursive List function, just setting up the initial stuff.
public static void printRecList(int k, int arr[], int index, int range) {
This is a recursive function, it should (and does) contain two main parts:
A base case (here, when k==0 )
A non-base case which does something, reducing the problem into smaller problem(s), and recurses.
Base case:
if (k == 0) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
If k==0, print out the numbers in the array from left to right, then put a new-line at the end.
Non-Base Case: (the more complicated part)
else {
for (int i = 1; i <= range; i++) {
if (index == 0) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
} else {
int t = arr[index-1]-i;
t = t > 0 ? t : -t;
if (t < 2) {
arr[index] = i;
printRecList(k - 1, arr, index + 1, range);
}
}
}
}
'i' goes from 1 to range,
The helper function calls this with index=0, so the first/top level of recursion, is composed of setting the first element (element 0) of the array to i, and calling the recursive method.
Never again will index == 0 in the recursive calls, so we turn our attention to the else clause.
Here we want to know if we can assign the value i to the next element over, so we check to see if the absolute value of elementToLeft minus i is greater than or equal to 2.
If 'i' is valid to assign in that position (i.e. it is only 1 or 0 different from the value to the left, and 'i' can only get as high as range from the for loop.)
Then we assign it, and check the next position over.
This ends when we have reached the last element in the array.

Categories