Arrays in Java - Core Java - java

In This Question A value is "everywhere" in an array if for every pair of adjacent elements in the array, at least one of the pair is that value. Return true if the given value is everywhere in the array.
isEverywhere({1, 2, 1, 3}, 1) → true,coz 1 is present in(1,2) and (1,3)
isEverywhere({1, 2, 1, 3}, 2) → false,coz 2 is in (1,2) but not in (1,3)
isEverywhere({1, 2, 1, 3, 4}, 1) → false,coz 1 is present in 2 pairs (1,2) and (1,3) but 4 is not having a pair of 1
My Partial working code is below,could you help me out with this problem,stuck up for a long time.
::Code::
public boolean isEverywhere(int[] nums, int val) {
boolean flag = false;
for(int i=0;i<nums.length;i++){
for(int j=i+2;j<nums.length;j++){
if(nums[i] == nums[j]){
flag = true;
}
}
}
return flag;
}
Result expected:
`Expected` `This` `Run`
isEverywhere({1, 2, 1, 3}, 1) → true true OK
isEverywhere({1, 2, 1, 3}, 2) → false true X
isEverywhere({1, 2, 1, 3, 4}, 1) → false true X

Try this:
boolean isEverywhere(int[] nums, int val) {
// use i+=2 to get start index of pair.
for(int i=0;i<nums.length;i+=2) {
// other index in the pair.
int j = i + 1;
// make sure the other index really exists.
if(j < nums.length) {
// if it exists..and val is not equal to
// either in the pair..return false.
if(nums[i] != val && nums[j] != val) {
return false;
}
} else {
// no pair..one element case.
// return true if that element is val..else return false.
return nums[i] == val;
}
}
// array has no unpaired element..and all pairs have val.
return true;
}

The key is
for every pair of adjacent elements in the array
Print out i and j before if(nums[i] == nums[j]) and you'd see what's going on.
For an array of length 2, you need (0, 1), for array of length 3, you need (0, 1), (1, 2), and so on.

You never use val in your code
Try figuring out the logic for that first
And this can be done with a single loop, try to figure out how you would as a person apply an algorithm, then code it

Your code is failing because the flag does not turn off in the case that the second loop goes beyond the array length.

Not a full solution, but if the length of the array is odd, check that the last value equals the target val
...
if( !(nums.length % 2) == 0 ){
if( nums[length-1] != val){
return false;
}
}
...

I did mine by simply counting if there are spaces:
Here it is in it's simple glory:
public boolean isEverywhere(int[] nums, int val) {
//Create an int to count the number of spaces between each instance of val.
int counter = 0;
//Create a for loop that checks val;
for (int i = 0; i < nums.length; i++)
{
//If the number at iteration i != val;
if (nums[i] != val)
{
//We increment the counter by one.
counter++;
}
//If the number does equal val, we put the counter back to 0;
else
{
counter = 0;
}
//If the counter is greater than or equal to two,
//We know that there is a space of more than 2, and so
//We return false;
if (counter >= 2)
{
return false;
}
}
//Return true if not false;
return true;
}

This code works fine:-
public boolean isEverywhere(int[] nums, int val) {
for(int i=0;i<=nums.length-2;i++){
if(nums[i]!=val&&nums[i+1]!=val){
return false;
}
}
return true;
}

public class IE {
static boolean isEverywhere(int[] a, int val) {
for (int i = 0; i < a.length; i++) {
System.out.println("*** iteration: " + i);
System.out.println("a[" + (i-1) + "]=" + (i > 0 ? a[i-1] : "n/a"));
System.out.println("a[" + i + "]=" + a[i]);
System.out.println("a[" + (i+1) + "]=" + (i < a.length -1 ? a[i+1] : "n/a"));
if (a[i] != val && (i > 0 ? a[i-1] != val : true) && (i < a.length-1 ? a[i+1] != val : true)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int[] a = new int[] {1, 2, 1, 3};
System.out.println(isEverywhere(a, 1));
a = new int[] {1, 2, 1, 3};
System.out.println(isEverywhere(a, 2));
a = new int[] {1, 2, 1, 3, 4};
System.out.println(isEverywhere(a, 1));
}
}
Basically, for a given element in the array, the test fails if the value isn't adjacent, either before or after it.

Related

isSorted? Check array if is sorted in ascending or descending order in Java

can someone help me check my codes if are right or help me know if there is any other is way to solve this question I was trying to check if an array is in ascending or descending order then return 1 if not then return 0; at first I created some method for sorting array in increasing order and order and another method for decreasing and then I used those method to compare with the original array if it is sorted. I used the code below:
public class IsSorted {
public static void main(String[] args){
int[] list ={4,3,2,1};
System.out.println(isSorted(list));
}
public static int isSorted(int[] a){
if(a.length==0){
return 1;
}
if(a.length==1){
return 1;
}
int[] holdingArray=new int[a.length];
for (int i =0; i<a.length; i++){
holdingArray[i]=a[i];
}
int[] virtualIncreasedArray= new int[holdingArray.length];
int[] virtualDecreasedArray= new int[holdingArray.length];
sortIncrease(holdingArray);
for(int i=0; i<holdingArray.length;i++){
virtualIncreasedArray[i]=holdingArray[i];
}
sortDecrease(holdingArray);
for(int i=0; i<holdingArray.length;i++){
virtualDecreasedArray[i]=holdingArray[i];
}
//check if array is decreasing
for(int i=0; i<virtualDecreasedArray.length;i++){
if(virtualDecreasedArray[i]!=a[i]&&virtualIncreasedArray[i]!=a[i]){
return 0;
}
}
//check if array is increasing
return 1;
}
static void sortIncrease(int[] a){
for(int unsorted=a.length-1; unsorted>0; unsorted--){
for(int i=0; i<unsorted;i++){
if(a[i]>a[i+1]){
swap(a,i,i+1);
}
}
}
}
static void sortDecrease(int[] a){
for(int unsorted=a.length-1; unsorted>0; unsorted--){
for(int i=0; i<unsorted; i++){
if(a[i]<a[i+1]){
swap(a,i,i+1);
}
}
}
}
static void swap(int[] a, int i, int j){
if(i==j){
return;
}
int temp = a[i];
a[i]=a[j];
a[j]=temp;
}
}
For an accurate verification, the following should be done as there are important side cases to consider.
Checking if any list starts out with some number of equal values.
Determine the starting index where the values first differ.
If all the values are equal, return true immediately.
Note that in the worst case when all the values are equal, the entire array needs to be checked (sans the last value since then it could be either ascending or descending).
int[] sortedAscending = { 1, 1, 3, 4, 7, 10, 11, 15, 15 };
int[] sortedDescending = { 22, 22, 12, 8, 8, 8, 5, 2, 1 };
int[] sortedBoth = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[] unsorted = { 2, 1, 2, 19, 19, 2, 4 };
System.out.println(isSorted(sortedAscending));
System.out.println(isSorted(sortedDescending));
System.out.println(isSorted(sortedBoth));
System.out.println(isSorted(unsorted));
Prints
true
true
true
false
The check method.
public static boolean isSorted(int[] arr) {
int start = 0;
// if the lists start with equal values, need to
// determine a starting point.
while (arr[start] == arr[start+1]
&& start++ < arr.length - 2);
if (start >= arr.length - 2) {
// all but the last the same value, its sorted
return true;
}
boolean asc = arr[start] < arr[start + 1];
for (int i = start; i < arr.length - 1; i++) {
if (asc) {
//check ascending
if (arr[i] > arr[i + 1]) {
return false;
}
// check descending
} else if (arr[i] < arr[i + 1]) {
return false;
}
}
return true;
}
Since you asked for another way to do this, here is a different approach.
What you could do is:
Determine whether the array is (supposedly) sorted in ascending or descending order based on the first 2 elements (if these exist)
Consider equal values when determining the supposed sorting (thanks for pointing that out #WJS)
Then, check the rest of the array for the correct order, based on what was determined
Updated Example:
public static void main(String[] args) {
int[] sortedAsc = { 1, 2, 3, 4, 5 };
int[] sortedDesc = { 5, 4, 2, 1 };
int[] unsortedArray = { 1, 8, 2, 4 };
int[] allEqual = { 3, 3, 3, 3, 3 };
int[] firstEqual = { 2, 2, 3, 2 };
System.out.println(isSorted(sortedAsc));
System.out.println(isSorted(sortedDesc));
System.out.println(isSorted(unsortedArray));
System.out.println(isSorted(allEqual));
System.out.println(isSorted(firstEqual));
}
public static boolean isSorted(int[] arr) {
boolean isAscending = false;
if (arr.length < 2) { // if the array has less than 2 elements, must be sorted
return true;
}
if (arr[0] < arr[1]) { // do we think this array is sorted ascending?
isAscending = true;
} else {
int index = 0;
while (arr[index] == arr[index + 1] && index++ < arr.length - 2) {
// keep checking for sorting if array consists of equal values
if (index >= arr.length - 2) {
return true; // whole array consists of equal values
}
}
// now that equal values were skipped, check for sorting again
isAscending = arr[index] < arr[index + 1];
}
// check all elements of the array
for (int i = 0; i < arr.length - 1; i++) {
if (isAscending) {
if (arr[i] > arr[i + 1]) {
return false;
}
} else {
if (arr[i] < arr[i + 1]) {
return false;
}
}
}
return true;
}
Output:
true
true
false
true
false
Sidenotes for your code:
Instead of returning an int (0, 1), your isSorted() method should definitely return boolean.
There is no point in the holdingArray.

How to check if there are 3 consecutive 1s in array in java?

simple example: array[6]
[1 1 1 0 0 0]
It is ok to have 3 of 1s in array but can not be consecutive.
If there are 3 consecutive 1s in a row, return false.
here is my code i am working on. I am trying y-(y-1)-(y-2) ==-1, return false but I cant make it work
Please show me good way to do it
I cannot find solutions on internet so if you know please direct the link.
New fixed: change from int[][]grid to int[] arr. Sorry for confusion
public static boolean checkOK(int[] arr) {
int limit = 3; //amount of number 1 can hay in each row and column
int countOne = 0;
for (int y = 0; y < grid.length; y++) {
if (arr[y] == 1)
countOne++; // increment countOnes
}
if (countOne > limit) { // false if amount of value 1 over 3
return false;
}
if (countOne == limit) {
// checking 3 consecutive 1s in array here?
return false;
}
return true;
}
for array above output should return false
I think your solution is close (apart from the syntax errors in your post).
The problem is that you are simply counting the number of 1's in the array, then after processing all of the elements in the array checking if there are three.
This would result in you getting a "false" return if there are three 1's anywhere in your array - contiguous or not.
The alternative is to increment the counter if you see a 1 like you are doing, but if you see something else, reset the counter to 0. Then, and this is the important bit, inside your loop check to see if you have reached the limit. If you have, then return false at that time.
The other problem that you might encounter is if your array has less than three elements in it. If you use logic such as array[i] == 1 && array[i-1] == 1 ... then you will either encounter index out of bounds exceptions and/or more complicated logic trying to avoid those exceptions.
Following is a full working example that addresses both problems.
package sequencechecker;
/**
* #author gmc
*/
public class SequenceChecker {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
SequenceChecker sc = new SequenceChecker();
int [] data = new int [] {1,1,1, 0, 0, 0};
sc.test (data);
data = new int [] { 1, 0, 1, 0, 1, 0};
sc.test(data);
data = new int [] {1, 1};
sc.test(data);
}
public void test(int [] array) {
System.out.print("for: ");
for (int i : array) {
System.out.print(i + " ");
}
System.out.println(check(array));
}
public static final int LIMIT = 3;
public boolean check(int [] array) {
int cntr = 0;
for (int i : array) {
if (i == 1) {
cntr++;
} else {
cntr = 0;
}
if (cntr >= LIMIT) {
return false;
}
}
return true;
}
}
The output is as follows:
for: 1 1 1 0 0 0 false
for: 1 0 1 0 1 0 true
for: 1 1 true
Keep track of the count of consecutive 1s and exit the loop if you hit 3.
static boolean checkOK(int[] arr)
{
int count = 0;
for(int i=0; count < 3 && i < arr.length; i++)
count = (arr[i] == 1) ? count + 1 : 0;
return count < 3;
}
Test
int[][] tests = {
{},
{1},
{1,1},
{1,1,1},
{0,1,1,1},
{1,1,1,0},
{0,1,1,1,0},
{0,1,0,1,0}
};
for(int[] test : tests)
System.out.format("%s : %s%n", Arrays.toString(test), checkOK(test));
Output:
[] : true
[1] : true
[1, 1] : true
[1, 1, 1] : false
[0, 1, 1, 1] : false
[1, 1, 1, 0] : false
[0, 1, 1, 1, 0] : false
[0, 1, 0, 1, 0] : true
Try this one:
public static void main(String args[]) {
int[] array = new int[]{1, 1, 1, 0, 0, 0};
System.out.println("IS OK? : " + checkOK(array));
}
public static boolean checkOK(int[] array) {
for(int i = 0; i < array.length; i++) {
if(!valid(array, i))
return false;
}
return true;
}
static boolean valid(int[] array, int index) {
if(index < 1 || index >= array.length - 1)
return true;
return !(array[index - 1] == array[index] && array[index] == array[index + 1]);
}
Does my code work for your problem?
int[] grid = new int[]{1,1,1,0,0,0};
for (int y = 0; y < grid.length - 2; y++) {
if (grid[y] == 1 && grid[y] == grid[y+1] && grid[y] == grid[y+2]) return false;
}
I'm not sure if the method needs to check if there are at least three, or if there are exactly three. This one is for at least three 1s (I don't have enough reputation to ask via comment).
This is the most straight foward approach I could think of, just having a counter and checking if it got to 3.
int countOne = 0;
for (int y = 0; y < grid.length && countOne < 3; y++) {
if (grid[y] == 1)
countOne++;
else
countOne = 0;
}
return countOne != 3;
One could at first put the countOne < 3 as a condition inside the loop with a break, as follows:
int countOne = 0;
for (int y = 0; y < grid.length; y++) {
if (grid[y] == 1) {
countOne++;
if (countOne == 3)
return false;
}
else
countOne = 0;
}
return true;
It's just that my teachers always insisted on not putting breaks inside loops unless you really need to.
The last return is true because there's no way to get out of the loop with three 1s as the method already returned false inside.
Try this.
int[] ar = {1,1,2,1,2,2,2,1,2,1,2,1,1,1,2,1,2,1,1};
System.out.println(isValid(ar));
int[] ar1 = {1,1,2,1,2,2,2,1,2,1,2,1,1,2,1,2,1,1};
System.out.println(isValid(ar1));
Prints
false
true
This simply counts up to three. If a digit not 1 is encountered, the count is reset to 0.
as soon as three consecutive 1's are found, the method returns false.
public static boolean isValid(int[] arr) {
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 1) {
count++;
if (count == 3) {
return false;
}
} else {
count = 0;
}
}
return true;
}
You can try this simple algorithm that increments if the item equals to one and reset it is zero, then check if the count greater than or equal to exceed then return false
public static boolean checkOK(int[] arr, int exceed) {
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 1) count++;
else count = 0;
if (count >= exceed)
return false;
}
return true;
}
, Main
public static void main(String[] args) {
System.out.println(checkOK(new int[] { 1, 1, 1, 0, 0, 0 }, 3));
System.out.println(checkOK(new int[] { 1, 0, 0, 1, 1, 1 }, 3));
System.out.println(checkOK(new int[] { 0, 1, 0, 1, 0 }, 3));
System.out.println(checkOK(new int[] { 0, 1, 1, 1, 0 }, 3));
}
, output
false
false
true
false

How to manage recursive function?

I need to write a recursive function that gets 4 parameters.
The 1st one is array. the 2nd one - left index, the 3rd one a right index and "K" index. "K" index is a cell in array , and the lrft index points to the start and the right one points to the end.
An array may contain such digitalis as zeros and ones. The method returns the maximum length of a sequence of ones that contain the cell k.
Here the example of the result that I need to get:
public static void main(String[] args) {
int[] A = {1,1,1,0,1,1,0,1,1,1,1,1,0,1,1};
System.out.println(floodOnes(A,0, A.length-1, 9)); // 5 output
System.out.println(floodOnes(A,0, A.length-1, 3)); // 0 output
System.out.println(floodOnes(A,0, A.length-1, 0)); // 3 output
System.out.println(floodOnes(A,0, A.length-1, 14)); // 2 output
}
public static int floodOnes(int [] A,int left, int right, int k){
//some logic
}
Here is my implementation:
public class Program {
public static void main(String[] args) {
int[] A = {1,1,1,0,1,1,0,1,1,1,1,1,0,1,1};
System.out.println(floodOnes(A,0,A.length-1, 9));
}
public static int floodOnes(int [] A,int left, int right, int k){
if (left != k) left+=1;
if (right != k) right-=1;
if (left == k && right == k) return A[k]; //condition when the recursive call stops
int res = floodOnes(A, left, right, k);
if (A[left] == 1 && A[right] == 1)
return res = A[left] + A[right]; //count ones
else return res;
}
}
But my solution not working properly.
In this rows:
if (A[left] == 1 && A[right] == 1)
return res = A[left] + A[right]; //count ones
If one of the conditions isn`t executed once, the following returns shouldn't add ones to result variable.
And I don't know how to do it.
I proved my comment wrong. Here is a recursive method with the 4 parameters mentioned in the question that indeed solves the problem.
public static int floodOnes(int[] a, int left, int right, int k) {
if (0 <= left && left <= k && k <= right && right < a.length) {
// is there a 0 between left (inclusive) and k (exclusive)?
int i = left;
while (i < k && a[i] == 1) {
i++;
}
if (i < k) {
assert a[i] == 0;
return floodOnes(a, i + 1, right, k);
}
// is there a 0 between k (exclusive) and right (inclusive)?
i = right;
while (i > k && a[i] == 1) {
i--;
}
if (i > k) {
assert a[i] == 0;
return floodOnes(a, left, i - 1, k);
}
// no zero found, a[k] not checked, though
if (a[k] == 0) {
return 0;
} else {
return right - left + 1;
}
} else {
throw new IllegalArgumentException("Expected " + left + " <= " + k + " <= " + right + " < " + a.length);
}
}
With this method, the first main method in your question prints the expected:
5
0
3
2
I really don’t see a point in solving the problem in this way, so I am far from sure this was what was intended. I’d prefer a non-recursive solution, or if it just needs to be recursive somehow, then the solution in Grzegorz Górkiewicz’ answer.
You can decompose this problem into 2 functions.
The first will count elements on the left-hand side, the latter on the right-hand side. Both use recursion.
public static int floodOnes(int[] A, int left, int right, int k) {
return checkLeft(A, left, k-1, A[k]) + 1 + checkRight(A, right, k+1, A[k]);
}
public static int checkLeft(int[] A, int leftBoundary, int k, int number) {
if (k < 0 || A[k] != number || k < leftBoundary)
return 0;
return 1 + checkLeft(A, leftBoundary, k-1, number);
}
public static int checkRight(int[] A, int rightBoundary, int k, int number) {
if(k >= A.length || A[k] != number || k > rightBoundary)
return 0;
return 1 + checkRight(A, rightBoundary, k+1, number);
}
I assume:
that 0 <= left <= k <= right < A.length;
that the solitary number should be counted as 1 (sequence of length 1) unlike your example. If you want it to be counted as 0, add if(A[k] != 1) return 0; or a similar condition in your floodOnes method.
Therefore:
System.out.println(floodOnes(A, 0, A.length - 1, 9)); // prints 5
System.out.println(floodOnes(A, 0, A.length - 1, 3)); // prints 1
System.out.println(floodOnes(A, 0, A.length - 1, 0)); // prints 3
System.out.println(floodOnes(A, 0, A.length - 1, 14)); // prints 2
Besides left and right parameters can be used for some input exceptions
(e.g. k > A.length).
Since you are looking for - the maximum length of a sequence of ones that contain the cell k. A simple and concise code to achieve this can be as follows.
public static void main(String[] args) {
int[] A = {1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1};
System.out.println(floodOnes(A, 0, A.length - 1, 9)); // prints 5
System.out.println(floodOnes(A, 0, A.length - 1, 3)); // prints 0
System.out.println(floodOnes(A, 0, A.length - 1, 0)); // prints 3
System.out.println(floodOnes(A, 0, A.length - 1, 14)); // prints 2
}
public static int checkLeft(int[] A, int k) {
return (k < 0 || A[k] != 1) ? 0 : 1 + checkLeft(A, k - 1);
}
public static int checkRight(int[] A, int k) {
return (k > (A.length - 1) || A[k] != 1) ? 0 : 1 + checkRight(A, k + 1);
}
public static int floodOnes(int[] A, int left, int right, int k) {
return (A[k] != 1) ? 0 : checkLeft(A, k - 1) + 1 + checkRight(A, k + 1);
}
It outputs the desired result.
5
0
3
2

How to iterate over array of integers to find a sequence based on an O(N) solution?

I saw following question and tried to find an answer for that.
Question: Given a sequence of positive integers A and an integer T, return whether there is a *continuous sequence* of A that sums up to exactly T
Example
[23, 5, 4, 7, 2, 11], 20. Return True because 7 + 2 + 11 = 20
[1, 3, 5, 23, 2], 8. Return True because 3 + 5 = 8
[1, 3, 5, 23, 2], 7 Return False because no sequence in this array adds up to 7
Note: We are looking for an O(N) solution. There is an obvious O(N^2) solution which is a good starting point but is not the final solution we are looking for.
My answer to above question is:
public class Tester {
public static void main(String[] args) {
int[] myArray = {23, 5, 4, 7, 2, 11};
System.out.println(isValid(myArray, 20));
}
public static boolean isValid(int[] array, int sum) {
int pointer = 0;
int temp = 0;
while (pointer < array.length)
{
for (int i = pointer; i < array.length; i++)
{
if (array[i] > sum)
break;
temp += array[i];
if (temp == sum)
return true;
else if (temp > sum)
break;
// otherwise continue
}
temp = 0;
pointer++;
}
return false;
}
}
I think my answer is O(N^2) which is not acceptable based on Question. Is there a solution based on O(N)?
You only need to loop once actually which is O(N).
Start adding from index 0 and once you exceed the sum start removing from the beginning of the array. if temp falls below sum continue looping.
public static boolean isValid(int[] array, int sum) {
int init = 0,temp = 0;
for (int i = 0; i < array.length; i++) {
temp += array[i];
while (temp > sum) {
temp -= array[init];
init++;
}
if (temp == sum)
return true;
}
return false;
}
What you should do is to have two indices (start and stop) then you increase stop until the sum is the required (and return true) or above. Then you increase start until the sum is the required (and return true or below. Then you repeat this until you reach the end of the array. You can update the sum incrementally (add the element when you increase stop and subtract when you increase start). This ought to be O(N).
Here's an example:
public class t {
public static void main(String[] args) {
int[] myArray = {23, 5, 4, 7, 2, 11};
System.out.println(isValid(myArray, 20));
}
public static boolean isValid(int[] array, int sum) {
int start = 0;
int stop = 0;
int tsum = 0;
while( true )
{
if( tsum < sum )
{
if( stop >= array.length )
break;
tsum += array[stop];
stop++;
}
else if( tsum > sum )
{
tsum -= array[start];
start++;
}
else if( tsum == sum )
return true;
// System.out.println(start + " -- " + stop + " => " + tsum);
}
return false;
}
}

Java grouping algorithm

Given an array of ints, is it possible to choose a group of some of the ints, such that the group sums to the given target, with this additional constraint: if there are numbers in the array that are adjacent and the identical value, they must either all be chosen, or none of them chosen. For example, with the array {1, 2, 2, 2, 5, 2}, either all three 2's in the middle must be chosen or not, all as a group. (one loop can be used to find the extent of the identical values).
The test scenarios are below
groupSumClump(0, {2, 4, 8}, 10) → true true OK
groupSumClump(0, {1, 2, 4, 8, 1}, 14) → true true OK
groupSumClump(0, {2, 4, 4, 8}, 14) → false false OK
groupSumClump(0, {8, 2, 2, 1}, 9) → true false X --->Failing
groupSumClump(0, {8, 2, 2, 1}, 11) → false false OK
groupSumClump(0, {1}, 1) → true false X --->Failing
groupSumClump(0, {9}, 1) → false false OK
other tests OK
Snippet is as below
private int sum(final Integer start, final Collection<Integer> list) {
int sum = start;
for (final int i : list) {
sum += i;
}
return sum;
}
public boolean groupSumClump(final int start, final int[] nums, final int target) {
for (int i = 0; i < nums.length-1; i++) {
if(nums[i] == nums[i+1]){//group selected logic
int sum = nums[i] + nums[i+1];//is this Ok ?
nums[i] =sum;
nums[i+1]=0;
}else{
//how to handle the logic for group not selected.
}
}
final List<Integer> fixed = new ArrayList();
final List<Integer> candidates = new ArrayList();
// fills candidates and fixed
for (int i = 0; i < nums.length; i++) {
final int cand = nums[i];
if (cand == 1 && i > 0) {
final int prev = nums[i - 1];
}else if (cand < target) {
candidates.add(cand);
}
}
// compute the sum of fixed
final int sumFixed = sum(0, fixed);
// if the sum of fixed is equals to target we don't need to do
//anything because we already know we need to return true.
if (sumFixed == target) {
return true;
}
if (sumFixed <= target && !candidates.isEmpty()) {
final Set<Set<Integer>> powerSets = powerSet(new HashSet(candidates));
for (final Set<Integer> set : powerSets) {
if (sumFixed + sum(0, set) == target) {
return true;
}
}
}
return false;
}
public <T> Set<Set<T>> powerSet(Set<T> originalSet) {
Set<Set<T>> sets = new HashSet<Set<T>>();
if(originalSet.isEmpty()) {
sets.add(new HashSet<T>());
return sets;
}
List<T> list = new ArrayList<T>(originalSet);
T head = list.get(0);
Set<T> rest = new HashSet<T>(list.subList(1, list.size()));
for (Set<T> set : powerSet(rest)) {
Set<T> newSet = new HashSet<T>();
newSet.add(head);
newSet.addAll(set);
sets.add(newSet);
sets.add(set);
}
return sets;
}
could you let me whats the problem with the code and why is it failing for test scenarios as mentioned.
i want to know what is the logic for group not selected?
Here is the full solution which passes all your test cases.
Please edit yourself to make it fit to your APIs ^_^
public static void main(String[] args) {
int nums [] = new int[]{2, 4, 8};
int target = 10;
int nums_another [] = grouped (nums);
System.out.println(viable(0, nums_another, 0, target));
}
private static int [] grouped (int nums []) {
int nums_another[] = new int [nums.length];
int i = 0;
int j = 0;
i++;
int c = 1;
while (i < nums.length){
if (nums[i] == nums[i-1]) { // count identical numbers
c++;
}
else { // not identical, store sum of previous identical numbers (possibly only 1 number)
if (nums[i-1] != 0) {
nums_another[j] = nums[i-1] * c;
j++;
}
c = 1;
}
i++;
}
if (nums[i-1] != 0) { // store last
nums_another [j] = nums[i-1] * c;
}
return nums_another;
}
/* partial_sum + sub array of "array from start to 0's" -> target */
private static boolean viable (int partial_sum, int array[], int start, int target) {
if (partial_sum == target) {
return true;
}
else if (start >= array.length || array[start] == 0) {
return false;
}
else { // Key step
return viable (partial_sum + array[start], array, start + 1, target)
|| viable (partial_sum, array, start + 1, target);
}
}
Key step:
return whether target is viable through sub array, test both cases start is included or not.
One helpful first step would be to replace the array with a LinkedMultiSet. Not a standard runtime collection but easy enough to imagine, find an implementation, or make.

Categories

Resources