Find longest possible sequence for jumps on next bigger number - java

Guys I am thinking on this problem several days and I have no solution even I have lots of experience.
Given a sequence of numbers, calculate the longest possible sequence of jumps from each number.
You can only jump on a number that is greater than the current one
You can jump on a number, only if there isn't one with a greater value between
You can jump only from left to right
I have this solution but I need to make it much faster:
private static List<Integer> slow(int[] numbers){
int n = numbers.length;
int initialJump = 0;
int next = 0;
List<Integer> list = new ArrayList<>();
int counter = 0;
int maxNum = Arrays.stream(numbers).max().getAsInt();
for (int i = 0; i < n; i++) {
initialJump = numbers[i];
if (initialJump == maxNum) {
list.add(0);
continue;
}
for (int j = i + 1; j < n; j++) {
next = numbers[j];
if (initialJump < next) {
counter++;
initialJump = next;
}
}
list.add(counter);
counter = 0;
}
return list;
}
Here is example:
Input
1 4 2 6 3 4
Output
2 1 1 0 1 0
Explanation
Element 1:
1 -> 4 -> 6 (2 jumps)
Element 2:
4 -> 6 (1 jump)
Element 3:
2 -> 6 (1 jump)
Element 4:
6 (0 jumps)
Element 5:
3 -> 4 (1 jump)
Element 6:
4 -> (0 jumps)
Do you have any idea?
Here is what I tried :
private static List<Integer> fast(int[] numbers){
int n = numbers.length;
int[] jumplist = new int[n];
int initialJump = 0;
int count = 0;
int maxNum = Arrays.stream(numbers).max().getAsInt();
Map<Integer, Integer> map = new HashMap<>();
for(int i=n-1; i>=0; i--) {
if(i-1 >= 0 && map.get(i+1) != null && numbers[i+1] > numbers[i]){
jumplist[i] = map.get(i+1)+1;
continue;
}
initialJump = numbers[i];
if (initialJump == maxNum) {
jumplist[i] = 0;
continue;
}
for(int j=i; j<n; j++) {
if(initialJump < numbers[j]) {
count++;
initialJump = numbers[j];
map.put(i,count);
}
}
jumplist[i] = count;
count = 0;
}
return Arrays.stream(jumplist).boxed().collect(Collectors.toList());
}
Here is some test code:
int randomLimit = 50000;
Random random = new Random();
List<Integer> randomList = new ArrayList<>();
for (int i = 0; i < randomLimit; i++) {
randomList.add(random.ints(0, randomLimit).findFirst().getAsInt());
}
System.out.println("Input: " + randomList.stream().limit(20).collect(Collectors.toList()));
int[] randomArray = randomList.stream().mapToInt(i->i).toArray();
Instant fastStarts = Instant.now();
List<Integer> fastRes = fast(randomArray);
System.out.println(fastRes.stream().limit(20).collect(Collectors.toList()));
Instant fastEnds = Instant.now();
System.out.println("fast: " + Duration.between(fastStarts, fastEnds).toMillis());
Instant slowStarts = Instant.now();
List<Integer> slowRes = slow(randomArray);
System.out.println(slowRes.stream().limit(20).collect(Collectors.toList()));
Instant slowEnds = Instant.now();
System.out.println("slow: " + Duration.between(slowStarts, slowEnds).toMillis());
if(slowRes.size() != fastRes.size()){
System.out.println("Not Equal Result !!");
}else {
for (int i = 0; i < slowRes.size(); i++) {
if (!slowRes.get(i).equals(fastRes.get(i))) {
System.out.println("Not Equal Result !!");
break;
}
}
}

Here is some optimized code but I need more optimized ...
private static List<Integer> fast(int[] numbers){
int n = numbers.length;
int[] jumplist = new int[n];
Arrays.fill(jumplist, -1);
int initialJump = 0;
int count = 0;
int maxNum = Arrays.stream(numbers).max().getAsInt();
for(int i=n-1; i>=0; i--) {
if(i+1 < n && jumplist[i+1] != -1 && numbers[i+1] > numbers[i]){
jumplist[i] = jumplist[i+1] + 1;
continue;
}
initialJump = numbers[i];
if (initialJump == maxNum) {
jumplist[i] = 0;
continue;
}
for(int j=i+1; j<n; j++) {
if(initialJump < numbers[j]) {
count++;
initialJump = numbers[j];
}
}
jumplist[i] = count;
count = 0;
}
return Arrays.stream(jumplist).boxed().collect(Collectors.toList());
}

Related

How to get sum of array elements between two zeros

first input: size of array: 5
second input: 0 -2 4 0 6
output: 2
Here is what I have tried. It is also adding the numbers before zero:
My code's output:
array size: 10
elements: 6 19 0 -3 4 8 0 -6 9 59
my output: 25 9
import java.util.Scanner;
import java.util.Vector;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
Vector<Integer> A = new Vector<Integer>();
int sum = 0;
for(int i=0; i<arr.length; i++){
arr[i] = in.nextInt();
}
for(int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
{
i++;
break;
}
}
for(int i=0; i < arr.length; i++)
{
if (arr[i] == 0)
{
A.add(sum);
sum = 0;
}
else
{
sum += arr[i];
}
}
for(int j = 0; j < A.size(); j++)
{
System.out.print(A.get(j) + " ");
}
}
}
You don't need 2 loops, one to look for the first zero and then sum up.
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
List<Integer> sums = new ArrayList<>();
int sum = 0;
// read input
for (int i = 0; i < arr.length; i++) {
arr[i] = in.nextInt();
}
boolean isCounting = false;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != 0 && isCounting) {
sum += arr[i];
} else if(arr[i] == 0){
// if already counting then finish the sum
if (isCounting) {
sums.add(sum);
sum = 0;
} else { // else start counting
isCounting = true;
}
}
}
System.out.println(sums);
}
}
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt();
int arr[] = new int[size];
for (int i = 0; i < arr.length; i++) {
arr[i] = in.nextInt();
}
int sum = 0;
int idx = 0;
while (arr[idx] != 0)
idx++; // After this, idx will be the index of the first 0
do {
idx++; // Keep looping from idx + 1 until the next 0
if (arr[idx] != 0 && idx < arr.length)
sum += arr[idx];
} while (idx < arr.length && arr[idx] != 0);
System.out.println("Sum = " + sum);
}
}
int sum = -1;
int j = -1;
for(int i=0; i<arr.length;i++ ){
if (arr[i] == 0) {
j = i;
if (sum == -1)
sum = 0;
else
break;
}
if ( j == -1)
continue;
sum += arr[i];
}
The above should work
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
int sum = 0;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
if (arr[i] == 0) {
list.add(i);
}
}
for (int i = list.get(0); i <= list.get(list.size()-1); i++) {
sum += arr[i];
}
System.out.println(sum);
}

Separating the 0s and Positive Numbers in two different arrays

This is the code I have written, My objective is to segregate the 0s and non 0s without changing the order of the non 0s
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int[] arx;
arx = new int[x];
int[] ary;
ary = new int[x];
for (int i = 0; i < x; i++) {
int q = sc.nextInt();
if (q != 0) {
arx[i] = q;
} else if (q == 0) {
ary[i] = q;
}
}
for (int j = 0; j < arx.length; j++) {
System.out.print(arx[j] + " ");
}
for (int j = 0; j < ary.length; j++) {
System.out.print(ary[j] + " ");
}
}
}
Sample i/p:
5
0 1 0 3 12
Sample o/p:
1 3 12 0 0
What I am getting:
o/p:
0 1 0 3 12 0 0 0 0 0
You should maintain separate index counters for the two arrays:
int x = sc.nextInt();
int ix = 0;
int iy = 0;
int[] arx;
arx = new int[x];
int[] ary;
ary = new int[x];
for (int i=0; i < x; i++) {
int q = sc.nextInt();
if (q != 0) {
arx[ix++] = q;
}
else if (q == 0) {
ary[iy++] = q;
}
}
for (int i=0; i < ix; i++) {
System.out.print(arx[i] + " ");
}
for (int i=0; i < iy; i++) {
System.out.print(ary[i] + " ");
}
For your inputs the above generated the following output:
1 3 12 0 0
Since array with arx is filled with zeroes , you can only use one array to add non zero values.
{
Scanner sc = new Scanner (System.in);
int x = sc.nextInt ();
int[] arx;
arx = new int[x];
int ind = 0;
for (int i = 0; i < x; i++) {
int q = sc.nextInt ();
if (q != 0){
arx[ind++] = q;
}
}
for (int j = 0; j < arx.length; j++){
System.out.print (arx[j] + " ");
}
}

Removing N duplicates from integer array

problem statement: I have to remove n duplicates from array.
Here is the full problem statement : https://pastebin.com/EJgKUGe3
and my solution is :
public class minion_labour_shift_2ndTry {
static int[] data = {1,2, 2, 3, 3, 3, 4, 5, 5};
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
data = answer(data, n);
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
}
public static int[] answer(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
int[] result = new int[99];
ArrayList<Integer> temp = new ArrayList<>();
int counter = 0, count ,maxCount = 0;
for (int i = 0; i < data.length; i++) {
boolean isDistinct = false;
for (int j = 0; j < i; j++) {
if (data[i] == data[j]) {
isDistinct = true;
break;
}
}
if (!isDistinct) {
result[counter++] = data[i];
}
}
for (int i = 0; i < counter; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (result[i] == data[j]) {
count++;
}
}
System.out.println("....... count"+count);
if (maxCount <= count){
maxCount = count;
}
if (count <= n){
temp.add(result[i]);
}
}
if (maxCount-1 < n){
return data;
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
}
Now, my question is, what I am missing and what should I do to pass all the 10 cases.
Thanks In Advance :)
NB:It will be compiled in java 7 , and Map,hashset or third-party libraries, input/output operations, spawning threads or processes and changes to the execution environment are not allowed.
I misread the requirements initially, this does what is asked:
public static int[] answer(int[] data, int n) {
Map<Integer, Integer> counts = new HashMap<>();
int elementsNeeded = 0;
for (int i = 0; i < data.length; i++) {
Integer currentCount = counts.get(data[i]);
currentCount = currentCount == null ? 1 : ++currentCount;
counts.put(data[i], currentCount);
if (currentCount <= n + 1) {
elementsNeeded += currentCount > n ? -n : 1;
}
}
int[] resultArray = new int[elementsNeeded];
int j = 0;
for (int i = 0; i < data.length; i++) {
if (counts.get(data[i]) <= n) {
resultArray[j++] = data[i];
}
}
return resultArray;
}
...and also your own code, slightly altered:
public static int[] answer2(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
ArrayList<Integer> temp = new ArrayList<>();
int count;
for (int i = 0; i < data.length; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (data[i] == data[j]) {
count++;
}
}
if (count <= n){
temp.add(data[i]);
}
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
Not going to provide a full solution but suggesting a reworking of the algorithm because it's not clear what you're doing, you never explained your actual thoughts of the algorithm. For example, what are you using isDistinct for?
1) Loop through once and compute the frequency of every number. You can just use an array of length 100 since that's all the data inputs will be. As you loop through, keep track of two things: The total number of entries that occur more than n times, as well as which those numbers are
2) Create a resulting array of the appropriate size (calculated from above) and loop through the list again and fill in the elements that didn't cross the threshold.

JAVA program bug when populating array from different array

When population oddList, evenList and negativeList from the inputList the program only populates it with one int instead of all corresponding ints from the inputList array. The output should be a list from each array whose numbers correspond to its title. The numbers are input by user into inputList array and then from there it determines whether it is odd, even, and negative and then fills the corresponding arrays.
I.E. evenList is filled with even ints from inputList.
public class ProjectTenOne
{
public static void main(String[] args)
{
int[] inputList = new int[10];
int[] oddList = null;
int[] evenList = null;
int[] negativeList = null;
int evenCount = 0;
int oddCount = 0;
int negCount = 0;
Scanner input = new Scanner(System.in);
//System.out.println("Enter any ten integers: ");
for(int list = 0; list < inputList.length; list++)
{
System.out.println("Enter any " + (inputList.length - list) + " integers: ");
inputList[list] = input.nextInt();
}
System.out.println();
System.out.println("The numbers you entered: ");
for(int in = 0; in < inputList.length; in++)
{
System.out.println(inputList[in]);
}
for(int ls = 0; ls< inputList.length; ls++)
{
if(inputList[ls] % 2 == 0)
{
evenCount = evenCount +1;
}
if(inputList[ls] % 2 != 0)
{
oddCount = oddCount +1;
}
if(inputList[ls] < 0)
{
negCount = negCount +1;
}
}
evenList = new int[evenCount];
oddList = new int[oddCount];
negativeList = new int[negCount];
for(int l = 0; l < inputList.length; l++)
{
if((inputList[l] % 2) == 0)
{
for(int j = 0; j < evenList.length; j++)
{
evenList[j] = inputList[l];
}
}
if((inputList[l] % 2) != 0)
{
for(int k = 0; k < oddList.length; k++)
{
oddList[k] = inputList[l];
}
}
if(inputList[l] < 0)
{
for(int h = 0; h < negativeList.length; h++)
{
negativeList[h] = inputList[l];
}
}
}
System.out.println("The ODD List is: ");
for(int i = 0; i < oddList.length; i++)
{
System.out.println(oddList[i]);
}
System.out.println("The EVEN List is: ");
for(int j = 0; j < evenList.length; j++)
{
System.out.println(evenList[j]);
}
System.out.println("The NEGATIVE List is: ");
for(int k = 0; k < oddList.length; k++)
{
System.out.println(negativeList[k]);
}
}
}
I'll take evenList as the example here, but the same applies to the other two arrays as well.
In your code, you iterate over your inputList and check for an even number. If it is even, you set the entire evenList array to the found value, instead of just a single element.
You can solve this problem by declaring an int outside of your outer loop that keeps track of the number of even numbers entered. As an example:
int evenIndex = 0;
for(int l = 0; l < inputList.length; l++)
{
if((inputList[l] % 2) == 0)
{
evenList[evenIndex++] = inputList[l];
}
/*Other code*/
}
You also made a mistake in your last loop. You iterate over negativeList, but you use the size of evenList. This will result in an ArrayIndexOutOfBoundsException when negativeList is smaller than evenList.

How to generate combinations obtained by permuting 2 positions in Java

I have this problem, I need to generate from a given permutation not all combinations, but just those obtained after permuting 2 positions and without repetition. It's called the region of the a given permutation, for example given 1234 I want to generate :
2134
3214
4231
1324
1432
1243
the size of the region of any given permutation is , n(n-1)/2 , in this case it's 6 combinations .
Now, I have this programme , he does a little too much then what I want, he generates all 24 possible combinations :
public class PossibleCombinations {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("Entrer a mumber");
int n=s.nextInt();
int[] currentab = new int[n];
// fill in the table 1 TO N
for (int i = 1; i <= n; i++) {
currentab[i - 1] = i;
}
int total = 0;
for (;;) {
total++;
boolean[] used = new boolean[n + 1];
Arrays.fill(used, true);
for (int i = 0; i < n; i++) {
System.out.print(currentab[i] + " ");
}
System.out.println();
used[currentab[n - 1]] = false;
int pos = -1;
for (int i = n - 2; i >= 0; i--) {
used[currentab[i]] = false;
if (currentab[i] < currentab[i + 1]) {
pos = i;
break;
}
}
if (pos == -1) {
break;
}
for (int i = currentab[pos] + 1; i <= n; i++) {
if (!used[i]) {
currentab[pos] = i;
used[i] = true;
break;
}
}
for (int i = 1; i <= n; i++) {
if (!used[i]) {
currentab[++pos] = i;
}
}
}
System.out.println(total);
}
}
the Question is how can I fix this programme to turn it into a programme that generates only the combinations wanted .
How about something simple like
public static void printSwapTwo(int n) {
int count = 0;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < n - 1;i++)
for(int j = i + 1; j < n; j++) {
// gives all the pairs of i and j without repeats
sb.setLength(0);
for(int k = 1; k <= n; k++) sb.append(k);
char tmp = sb.charAt(i);
sb.setCharAt(i, sb.charAt(j));
sb.setCharAt(j, tmp);
System.out.println(sb);
count++;
}
System.out.println("total=" + count+" and should be " + n * (n - 1) / 2);
}

Categories

Resources