Java longest subsequence - java

I have an array, i'd like to calculate the length of the longest subsequence made by equals numbers:
Example: 5 1 1 9 9 9 4 4 6 6 4 4 4 --> the length of the longest subsequence is 3 (9 9 9).
This is what i got so far but it doesn't work.
int lung=0, lungmax=0;
int indice = 0;
int [] values = new int [30];
for(int k=0; k<30; k++)
{
if (values[k]==values[k+1])
{
lung++;
if (lung>lungmax)
{
lungmax=lung;
indice=values[k];
}
}
else lung=0;
}
lungmax = lungmax++;
System.out.println("the length of the longest subsequence is: "+lungmax);

Your code has two errors:
for(int k=0; k<30; k++) {
if (values[k]==values[k+1]) {
This loop will be executed until k reaches value 30. Therefore, the last used value for k is 29. If you use that value in the if statement, you'll exceed that array bounds by calling values[k+1] (== values[30]).
Change that loop to:
for(int k = 0; k < values.length - 1; k++) {
The second problem is this line:
lungmax = lungmax++;
This is the same as:
int temp = lungmax;
lungmax = lungmax + 1;
lungmax = temp;
As you can see, you're "ignoring" the increment. Change that line to:
lungmax++;

Try this. By applying my approach, the ArrayIndexOutOfBoundsException has been eliminated.
public static void main(String args[]) {
int lung = 1, lungmax = 0;
int indice = 0;
int[] values = {1, 2, 2, 3, 3, 3, 5, 5, 5, 5, 6};
for (int k = 1; k < values.length; k++) {
if (values[k - 1] == values[k]) {
lung++;
if (lung > lungmax) {
lungmax = lung;
indice = values[k];
}
} else {
lung = 1;
}
}
System.out.println("the length of the longest subsequence is: " + indice + "/" + lungmax);
}

Or simply
make following changes
int lungmax=1;
and replace
lungmax=lung
with
lungmax++;
and remove last lungmax=lungmax++
plus what Tom suggested : k<30-1

Related

Minimum count of numbers required from given array to represent S

Given an integer S and an array arr[], the task is to find the minimum number of elements whose sum is S, such that an element of the array can be chosen only once to get sum S.
Example:
Input: arr[] = {25, 10, 5}, S = 30
Output: 2
Explanation:
Minimum possible solution is 2, (25+5)
Example:
Input: arr[] = {2, 1, 4, 3, 5, 6}, Sum= 6
Output: 1
Explanation:
Minimum possible solution is 1, (6)
I have found similar solution here but it says element of array can be used multiple times.
I have this code from the link which uses an array element multiple times, but how to restrict this to use only once?
static int Count(int S[], int m, int n)
{
int [][]table = new int[m + 1][n + 1];
// Loop to initialize the array
// as infinite in the row 0
for(int i = 1; i <= n; i++)
{
table[0][i] = Integer.MAX_VALUE - 1;
}
// Loop to find the solution
// by pre-computation for the
// sequence
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if (S[i - 1] > j)
{
table[i][j] = table[i - 1][j];
}
else
{
// Minimum possible for the
// previous minimum value
// of the sequence
table[i][j] = Math.min(table[i - 1][j],
table[i][j - S[i - 1]] + 1);
}
}
}
return table[m][n];
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 9, 6, 5, 1 };
int m = arr.length;
System.out.print(Count(arr, m, 11));
}
The idiomatic approach for this is to loop backwards when updating the table of previous results.
static int minElementsForSum(int[] elems, int sum){
int[] minElems = new int[sum + 1];
for(int i = 1; i <= sum; i++) minElems[i] = Integer.MAX_VALUE;
for(int elem: elems)
for(int i = sum; i >= elem; i--)
if(minElems[i - elem] != Integer.MAX_VALUE)
minElems[i] = Math.min(minElems[i], minElems[i - elem] + 1);
return minElems[sum];
}
Demo

How can I count these duplicate integers? [duplicate]

This question already has answers here:
How to count duplicate elements in ArrayList?
(13 answers)
Closed 4 years ago.
I must not modify the contents of the array, like using Array.sort().
Expected return of this code is 6, because there are three duplicates of the value 1, one duplicate of the value 2, and two duplicates of the value 4. but mine is showing 10. I know the reason why it is 10: it's counting the duplicates multiple times.
How can I make this code check duplicate integer only once?
private int count = 0;
public void run() {
int[] a = {1, 4, 2, 4, 7, 1, 1, 9, 2, 3, 4, 1};
println(countDuplicates(a));
}
private int countDuplicates(int[] a) {
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] == a[j]) {
count++;
}
}
}
return count;
}
One option would be to take the current size minus the size with duplicates removed:
Set<Integer> set = new HashSet<>();
for (int i=0; i < a.length; ++i) {
set.add(a[i]);
}
int numDuplicates = a.length - set.size();
There is probably a sleek way to populate a set of Integer from an array of primitive int using streams in Java 8.
Here you go with simple to understand logic for leaners
public static void main(String[] args) throws IOException {
int []a ={1, 4, 2, 4, 7, 1, 1, 9, 2, 3, 4, 1};
Map<Integer, Integer> occurances = new HashMap<>();
for(int i = 0; i < a.length; i++) {
//Check the is already occurred if not then add occurrence as 1
if (!occurances.containsKey(a[i])) {
occurances.put(a[i], 1);
}
// Second occurrences for a number
else {
occurances.put(a[i], occurances.get(a[i]) + 1);
}
}
System.out.println(occurances);
System.out.println("Total Numbers: "+a.length);
System.out.println("Duplicate count is "+ (a.length - occurances.size()));
}
Sort the array in-place.
Run through the array once, and count how many times current value is equal to previous value.
(Assuming you are allowed to use a library method to sort the array)
private static int countDuplicates(final int[] a)
{
int count = 0;
Arrays.sort(a); // sort array, you can use any way for it
for (int i = 0; i < a.length - 1; i++)
{
if (a[i] == a[i + 1]) // check only next element
{
count++;
}
}
return count; // return 6
}

Returning the number of unique numbers in a sorted array [duplicate]

This question already has answers here:
How to efficiently remove duplicates from an array without using Set
(48 answers)
Closed 7 years ago.
I was asked to write a method that accepts a sorted array, removes any duplicate elements found in the array and then places a 0 at the end of the array for every duplicate element found.
It is also supposed to return the number of unique elements found in the array.
Here is my method:
public static int removeDups(int[] arr) {
int j = 0;
int i = 1;
int numDups = 0;
while(i < arr.length) {
if (arr[i] == arr[j]) {
i++;
numDups++;
}
else {
arr[++j] = arr[i++];
}
}
for (int k = j+1; k < arr.length; k++) {
arr[k] = 0;
}
return (j);
}
It successfully finds all the duplicate numbers in the array and places the correct number of 0s at the end, but it doesn't always return the correct value for the number of unique elements.
For example, for the array:
{ 6 10 19 21 23 26 27 36 38 45 }
the number of unique elements should be 10, but it returns 9.
What am I doing wrong?
As it can be seen, j is used as the index of the last unique element.
In an array, i'th index is actually the i + 1'th element counted from 1.
So, you have to return j + 1 instead of j from your method.
Here is a solution to your problem. It keeps track of two pointers, one which only advances when a value gets written to the array, and the other which touches every element of the array in sequential order. When one or more duplicates are encountered, the second pointer keeps advancing, while the first pointer stays put, waiting to write a non-duplicate value. Finally, the code iterates over the remainder of the array from the first pointer, writing out zeroes until the end.
public static int removeDups(int[] arr) {
if (arr == null) {
return null;
}
if (arr.length == 0 || arr.length == 1) {
return arr;
}
int prevIndex = 0;
for (int i=1; i < arr.length; ++i) {
if (arr[prevIndex] != arr[i]) {
arr[prevIndex+1] = arr[i];
++prevIndex;
}
}
for (int i=prevIndex+1; i < arr.length; ++i) {
arr[i] = 0;
}
return prevIndex+1;
}
int[] arr = {1, 2, 3, 3, 4, 5, 6, 6, 6, 10};
removeDups(arr);
System.out.println(Arrays.toString(arr));
Output:
[1, 2, 3, 4, 5, 6, 10, 0, 0, 0]
This code has been tested using IntelliJ and it appears to be working.
Try this!
static int getUniqueElements(int [] sortedArr){
int duplicateCount = 0;
int [] tempArr = sortedArr;
int j=0;
boolean isNewValue = true;
for(int i=1;i<tempArr.length;i++){
if(sortedArr[j] != tempArr[i]){
isNewValue = true;
sortedArr[++j] = tempArr[i];
}else{
if(isNewValue){
isNewValue = false;
duplicateCount++;
}
}
}
for(j++;j<sortedArr.length;j++){
sortedArr[j] = 0;
duplicateCount++;
}
return (sortedArr.length-duplicateCount);
}
public static void main(String[] args) {
int[] arr = {1, 3, 3, 3, 3, 6, 6, 7, 8, 8};
System.out.println("Unique Count:"+ getUniqueElements(arr));
System.out.println(Arrays.toString(arr));
}
OutPut:
Unique Count:2
[1, 3, 6, 7, 8, 0, 0, 0, 0, 0]
Since in the given array 1,7 are unique.
Note: tried with your example array {6, 10, 19, 21, 23 ,26 ,27 ,36 ,38, 45 } also
My solution is as(assuming elements can repeat only twice):
public static int removeDups(int[] arr) {
int i = 0;
int numDups = 0;
while (i < arr.length - 1 - numDups) {
if (arr[i] == arr[i + 1]) {
numDups++;
for (int m = i + 1; m < arr.length - numDups; m++) {
arr[m] = arr[m + 1];
}
arr[arr.length - numDups] = 0;
}
i++;
}
return arr.length-numDups;
}

Java - how to stop nested loops from checking same indices twice?

Given an array and a number N call a pair of numbers from the array a Perfect Pair if their sum is equal to N.
Find all of the perfect pairs and return the sum of their indices. Note that any element of the array can only be counted in one Perfect Pair.
Examples
pairwise([1, 4, 2, 3, 0, 5], 7) = 11
Since the Perfect Pairs are (4, 3) and (2, 5) with indices 1 + 3 + 2 + 5 = 11.
pairwise([1, 3, 2, 4], 4) = 1
Since the element at index 0 (i.e. 1) and the element at index 1 (i.e. 3) form the only Perfect Pair.
Input 1 (arr) ā†’ array.integer :
array of non-negative integers
Input 2 (N) ā†’ integer :
positive integer
Output ā†’ integer :
sum of indices and 0 if no Perfect Pair exists
My Code:
public static void main(String[] args) {
int x[] = {1,4,2,3,0,5};
System.out.println(pairwise(x, 7));
}
public static int pairwise(int[] arr, int N) {
int t=0;
for(int i=0;i<arr.length;i++){
for(int k=0;k<arr.length;k++){
if(arr[i]+arr[k] == N){
t+=i+k;
}
}
}
return t;
}
The problem is my code checks indices twice, like (0,1) and (1,0) are treated like different indices.
The simplest options is to not check these in the first place. I assume i == k is not valid so you don't want to check k < i either.
public static void main(String[] args) {
int x[] = {1, 4, 2, 3, 0, 5};
System.out.println(pairwise(x, 7));
}
public static int pairwise(int[] arr, int N) {
int t = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int k = i + 1; k < arr.length; k++) {
if (arr[i] + arr[k] == N) {
t += i + k;
arr[i] = arr[k] = Integer.MIN_VALUE; // don't use these again
continue;
}
}
}
return t;
}
prints
11
This ensures you won't go over the same numbers twice.
Note: this is an O(n^2) approach, if you have more numbers you will want an O(n) approach which means using a set or map of numbers.
// O(n)
Map<Integer, Integer> intToIndex = new HashMap<>();
for(int i = 0; i < arr.length; i++)
intToIndex.put(arr[i], i);
// O(n)
for(int i = 0; i < arr.length; i++) {
int numberToLookFor = N - arr[i];
Integer k = intToIndex.get(numberToLookFor);
if (k != null) {
assert arr[i] + arr[k] == N;
// do something with i and k
}
}
Start the second loop from i, not 0.
for(int i = 0; i < 10; i++)
{
for(int j = i; j < 10; j ++)
{
System.out.println("(" + i + "," + j + ")");
}
}
Output:
I reduced `10` to `4`.
(0,0)
(0,1)
(0,2)
(0,3)
(0,4)
(1,1)
(1,2)
(1,3)
(1,4)
(2,2)
(2,3)
(2,4)
(3,3)
(3,4)
(4,4)

Printing out the least occurring elements in an array

OK, so I found this question from a few days ago but it's on hold and it won't let me post anything on it.
***Note: The values or order in the array are completely random. They should also be able to be negative.
Someone recommended this code and was thumbed up for it, but I don't see how this can solve the problem. If one of the least occurring elements isn't at the BEGINNING of the array then this does not work. This is because the maxCount will be equal to array.length and the results array will ALWAYS take the first element in the code written below.
What ways are there to combat this, using simple java such as below? No hash-maps and whatnot. I've been thinking about it for a while but can't really come up with anything. Maybe using a double array to store the count of a certain number? How would you solve this? Any guidance?
public static void main(String[] args)
{
int[] array = { 1, 2, 3, 3, 2, 2, 4, 4, 5, 4 };
int count = 0;
int maxCount = 10;
int[] results = new int[array.length];
int k = 0; // To keep index in 'results'
// Initializing 'results', so when printing, elements that -1 are not part of the result
// If your array also contains negative numbers, change '-1' to another more appropriate
for (int i = 0; i < results.length; i++) {
results[i] = -1;
}
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) { // <= so it admits number with the SAME number of occurrences
maxCount = count;
results[k++] = array[i]; // Add to 'results' and increase counter 'k'
}
count = 0; // Reset 'count'
}
// Printing result
for (int i : results) {
if (i != -1) {
System.out.println("Element: " + i + ", Number of occurences: " + maxCount);
}
}
}
credit to: https://stackoverflow.com/users/2670792/christian
for the code
I can't thumbs up so I'd just like to say here THANKS EVERYONE WHO ANSWERED.
You can also use an oriented object approach.
First create a class Pair :
class Pair {
int val;
int occ;
public Pair(int val){
this.val = val;
this.occ = 1;
}
public void increaseOcc(){
occ++;
}
#Override
public String toString(){
return this.val+"-"+this.occ;
}
}
Now here's the main:
public static void main(String[] args) {
int[] array = { 1,1, 2, 3, 3, 2, 2, 6, 4, 4, 4 ,0};
Arrays.sort(array);
int currentMin = Integer.MAX_VALUE;
int index = 0;
Pair[] minOcc = new Pair[array.length];
minOcc[index] = new Pair(array[0]);
for(int i = 1; i < array.length; i++){
if(array[i-1] == array[i]){
minOcc[index].increaseOcc();
} else {
currentMin = currentMin > minOcc[index].occ ? minOcc[index].occ : currentMin;
minOcc[++index] = new Pair(array[i]);
}
}
for(Pair p : minOcc){
if(p != null && p.occ == currentMin){
System.out.println(p);
}
}
}
Which outputs:
0-1
6-1
Explanation:
First you sort the array of values. Now you iterate through it.
While the current value is equals to the previous, you increment the number of occurences for this value. Otherwise it means that the current value is different. So in this case you create a new Pair with the new value and one occurence.
During the iteration you will keep track of the minimum number of occurences you seen.
Now you can iterate through your array of Pair and check if for each Pair, it's occurence value is equals to the minimum number of occurences you found.
This algorithm runs in O(nlogn) (due to Arrays.sort) instead of O(nĀ²) for your previous version.
This algorithm is recording the values having the least number of occurrences so far (as it's processing) and then printing all of them alongside the value of maxCount (which is the count for the value having the overall smallest number of occurrences).
A quick fix is to record the count for each position and then only print those whose count is equal to the maxCount (which I've renamed minCount):
public static void main(String[] args) {
int[] array = { 5, 1, 2, 2, -1, 1, 5, 4 };
int[] results = new int[array.length];
int minCount = Integer.MAX_VALUE;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
results[i]++;
}
}
if (results[i] <= minCount) {
minCount = results[i];
}
}
for (int i = 0; i < results.length; i++) {
if (results[i] == minCount) {
System.out.println("Element: " + i + ", Number of occurences: "
+ minCount);
}
}
}
Output:
Element: 4, Number of occurences: 1
Element: 7, Number of occurences: 1
This version is also quite a bit cleaner and removes a bunch of unnecessary variables.
This is not as elegant as Iwburks answer, but I was just playing around with a 2D array and came up with this:
public static void main(String[] args)
{
int[] array = { 3, 3, 3, 2, 2, -4, 4, 5, 4 };
int count = 0;
int maxCount = Integer.MAX_VALUE;
int[][] results = new int[array.length][];
int k = 0; // To keep index in 'results'
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] == array[i]) {
count++;
}
}
if (count <= maxCount) {
maxCount = count;
results[k++] = new int[]{array[i], count};
}
count = 0; // Reset 'count'
}
// Printing result
for (int h = 0; h < results.length; h++) {
if (results[h] != null && results[h][1] == maxCount ) {
System.out.println("Element: " + results[h][0] + ", Number of occurences: " + maxCount);
}
}
Prints
Element: -4, Number of occurences: 1
Element: 5, Number of occurences: 1
In your example above, it looks like you are only using ints. I would suggest the following solution in that situation. This will find the last number in the array with the least occurrences. I assume you don't want an object-oriented approach either.
int [] array = { 5, 1, 2, 40, 2, -1, 3, 2, 5, 4, 2, 40, 2, 1, 4 };
//initialize this array to store each number and a count after it so it must be at least twice the size of the original array
int [] countArray = new int [array.length * 2];
//this placeholder is used to check off integers that have been counted already
int placeholder = Integer.MAX_VALUE;
int countArrayIndex = -2;
for(int i = 0; i < array.length; i++)
{
int currentNum = array[i];
//do not process placeholders
if(currentNum == placeholder){
continue;
}
countArrayIndex = countArrayIndex + 2;
countArray[countArrayIndex] = currentNum;
int count = 1; //we know there is at least one occurence of this number
//loop through each preceding number
for(int j = i + 1; j < array.length; j++)
{
if(currentNum == array[j])
{
count = count + 1;
//we want to make sure this number will not be counted again
array[j] = placeholder;
}
}
countArray[countArrayIndex + 1] = count;
}
//In the code below, we loop through inspecting each number and it's respected count to determine which one occurred least
//We choose Integer.MAX_VALUE because it's a number that easily indicates an error
//We did not choose -1 or 0 because these could be actual numbers in the array
int minNumber = Integer.MAX_VALUE; //actual number that occurred minimum amount of times
int minCount = Integer.MAX_VALUE; //actual amount of times the number occurred
for(int i = 0; i <= countArrayIndex; i = i + 2)
{
if(countArray[i+1] <= minCount){
minNumber = countArray[i];
minCount = countArray[i+1];
}
}
System.out.println("The number that occurred least was " + minNumber + ". It occured only " + minCount + " time(s).");

Categories

Resources