Write a method that takes an array of integers and returns the length of its longest subarray with distinct integers.
e.g. with [1,2,3,4,2,3] it should return 4.
I used a HashSet to keep track of all elements from index i to index j and kept a counter while traversing through the list. Linear runtime and space:
public static int longestSubarray(int[] arr) {
int i = 0, j = 1, max = 0, currLength = 1;
max = Math.max(max, currLength);
HashSet<Integer> set = new HashSet<Integer>();
set.add(arr[0]);
while (i < arr.length - 1 && j < arr.length) {
if (!set.contains(arr[j])) {
currLength++;
set.add(arr[j++]);
}
else {
set.remove(arr[i++]);
currLength--;
}
}
return Math.max(currLength, max);
}
public int[] getLargestSubArray(int[] array) {
int length = array.length;
Set<Integer> set = new HashSet<>();
int longest = 0;
int start = 0;
int longestCurrent = 0;
int startCurrent = 0;
int j = 0;
while (j < length) {
if (!set.contains(array[j])) {
set.add(array[j]);
longestCurrent++;
if (longestCurrent > longest) {
longest = longestCurrent;
start = startCurrent;
}
j++;
} else {
while (startCurrent < j) {
longestCurrent--;
if (array[startCurrent++] == (array[j])) {
break;
}
}
set.remove(array[j]);
}
}
int[] longestSubSequence = new int[longest];
System.arraycopy(array, start, longestSubSequence, 0, longest);
return longestSubSequence;
}
public static int sizeOfLongestDistinctSubArrayO1(int[] arr) {
int max = 0;
Map<Integer, Integer> counts = new HashMap<>();
int cur = 0;
int prev = 0;
for (int i = 0, len = arr.length; i < len; i++) {
if (counts.containsKey(arr[i])) {
int j = counts.get(arr[i]);
max = Math.max(max, cur);
prev = Math.max(j, prev);
cur = i - prev;
counts.put(arr[i], i);
} else {
cur++;
counts.put(arr[i], i);
}
}
return Math.max(max, cur);
}
python version
#!/usr/bin/env python3
input = [1,2,3,4,2,3,4,5,6,7,3,4]
tmp_list = []
max = 0
for i in input:
if i not in tmp_list:
tmp_list.append(i)
else:
max = len(tmp_list) if len(tmp_list) > max else max
tmp_list = [i]
print (max if max >= len(tmp_list) else len(tmp_list))
public int lengthOfLongestSubarray(int[] arr) {
int max = 0; // Maximum length of subarray with unique elements
Map<Integer,Integer> map = new HashMap<>();
// let longest subarray starts at i and ends at j
for(int i = -1,j = 0; j < arr.length;j++) {
if(map.containsKey(arr[j])) {
i = Math.max(i,map.get(arr[j]));
}
max = Math.max(max,j-i);
map.put(arr[j],j);
}
return max;
}
C# Version
Core Logic:
private static int Solve(string s) {
var dict = new Dictionary < string,int > ();
var arr = s.Split(" ", StringSplitOptions.RemoveEmptyEntries);
var start = 0;
var substrLen = 0;
for (var i = 0; i < arr.Length; i++) {
if (dict.ContainsKey(arr[i])) {
substrLen = substrLen < i - start ? i - start: substrLen;
var tempStart = dict[arr[i]] + 1;
for (var j = dict[arr[i]]; j > start; j--) {
dict.Remove(arr[i]);
}
start = tempStart;
dict[arr[i]] = i;
}
else {
dict.Add(arr[i], i);
}
}
return dict.Count;
}
Complete code here
import java.util.*;
class GFG{
static int largest_subarray(int a[], int n)
{
HashSet<Integer> set = new HashSet<Integer>();
int ans = 0;
int counter = 0;
for(int i = 0; i < n; i++)
{
if(set.contains(a[i])){
set.clear();
counter =0;
}
set.add(a[i]);
counter++;
ans = Math.max(ans, counter);
}
// Return final ans
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 4, 4, 5, 6, 7, 8, 3, 4, 5, 3, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4
};
int n = arr.length;
System.out.print(largest_subarray(arr, n));
}
}
Related
I am trying to get an output of [4,6,6,7] with length 4 where arr[i] <= arr[i+1] where it is non-decreasing and it is contiguous. I know what i have to do but i dont know how to do it. my code prints out [3,4,6,6,7]. I am just having trouble on the contiguous part, any help? im not allowed to use extra arrays.
public static void ascentLength(int arr[], int size) {
int length = 0;
int index = 0;
int count = 1;
for (int i = 0; i < size-1; i++) {
index = i;
if (arr[0] <= arr[i+1] && count >0) {
System.out.println(arr[i]+ " index:" + index);
length++;
count++;
}
if (arr[0] >= arr[i+1]) {
}
}
System.out.println("length: " + length);
}
/* Driver program to test above function */
public static void main(String[] args) {
int arr[] = {5, 3, 6, 4, 6, 6, 7, 5};
int n = arr.length;
ascentLength(arr, n);
}
Here is my solution, it would be easier, if you could work with List, but this works for arrays:
public static void ascentLength(int arr[], int size) {
if(size == 1) System.out.println("length: 1");
// variables keeping longest values
int longestStartingIndex = 0;
int longestLength = 1;
// variables keeping current values
int currentStartingIndex = 0;
int currentCount = 1;
for (int i = 1; i < size; i++) {
if (arr[i-1] <= arr[i]) {
currentCount++;
} else {
// check if current count is the longest
if(currentCount > longestLength) {
longestLength = currentCount;
longestStartingIndex = currentStartingIndex;
}
currentStartingIndex = i;
currentCount = 1;
}
}
if(currentCount > longestLength) {
longestLength = currentCount;
longestStartingIndex = currentStartingIndex;
}
}
By using following I am able to find most frequently occurring integer in an array. But following code it will not work for few scenarios. How can I fix the code inside for loop? I want to enhance this approach only.
class FindingMostFrequencyOccur {
public static void main(String args[]) {
int A[] = { 1, 2, 3, 3, 1, 3, 1};
int M = 3; // Maximum Number in Array
int result = findFrequency(M, A);
System.out.println("Result "+result);
}
static int findFrequency(int M, int[] A) {
int N = A.length;
int[] count = new int[M + 1];
for (int i = 0; i <= M; i++)
count[i] = 0;
int maxOccurence = 1;
int index = -1;
for (int i = 0; i < N; i++) {
if (count[A[i]] > 0) {
int tmp = count[A[i]];
if (tmp > maxOccurence) {
maxOccurence = tmp;
index = i;
}
count[A[i]] = tmp + 1;
} else {
count[A[i]] = 1;
}
}
return A[index];
}
}
Can you we improve in this line
if (count[A[i]] > 0) {
int tmp = count[A[i]];
if (tmp > maxOccurence) {
maxOccurence = tmp;
index = i;
}
count[A[i]] = tmp + 1;
} else {
count[A[i]] = 1;
}
To get the frequency of m in a use:
static int findFrequency(int m, int[] a) {
return (int)IntStream.of(a).filter(i-> i==m).count();
}
To get a map of all frequencies in a use:
static Map<Integer, Integer> findFrequency(int[] a) {
Map<Integer, Integer> m = new HashMap<>();
IntStream.of(a).distinct().forEach(i->{
m.put(i, findFrequency(i,a));
});
return m;
}
In this logic, you take each element of the array, and find the number of times it is repeated to the right of it, in the array. This is given by local_frequency. If this happens to be more than max_frequency, then this number at arr[i] is stored in number, and then max_frequency stores local_frequency
public static void main(String[] args)
{
int[] arr = {1, 2, 3, 4, 3, 2, 1, 5, 5, 5, 4, 4, 3, 4};
int result = findMostFrequent(arr);
System.out.println(result + " is the most frequent number");
}
public static int findMostFrequent(int[] arr)
{
int number = arr[0];
int maxFrequency = 0;
for(int i =0 ; i < arr.length; i++)
{
int local_frequency = 0;
for(int j = i; j < arr.length; j++)
{
if(arr[i] == arr[j])
local_frequency++;
}
if(local_frequency > maxFrequency)
{
number = arr[i];
maxFrequency = local_frequency;
}
}
return number;
}
Check if there exists a Palindrome Number in the list.
If found return its size, else return -1.
public class Program{
public static boolean palindrome(String list){
String reversedString = "";
for (int i = list.length() -1; i >=0; i--){
reveresedString += list.charAt(i)
}
return list.equals(revereseString);
}
}
sample input: [3,5,2,6,3,6,2,1]
palindrome number found: [2,6,3,6,2]
sample output: 5
Here is a pseudo code.
output = -1;
for (i = 0; i < list.length; i++){
num = list[i];
indices[] = \\ get all the indices which the "num" value appears, only include those indices that are greater than "i"
for (j = 0; j < indices.length; j++){
flag = true;
k = i;
for (l = indices[j]; l >= k; l--, k++){
if (list[k] != list[l]) {
flag = false;
break;
}
}
if (flag){
length = (indices[j] - i) + 1;
if (length != 1 && length > output) { // checking of length != 1 will exclude those palindromes of length 2
output = length;
}
}
}
}
return output;
Here is the full code.
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
int[] list = { 3, 5, 2, 2, 6, 3, 6, 3, 6, 3, 6, 2, 2, 1 };
System.out.print(palindrome(list));
}
public static int palindrome(int[] list) {
int output = -1;
for (int i = 0; i < list.length; i++) {
int num = list[i];
ArrayList<Integer> indices = getIndices(list, i, num);
for (int j = 0; j < indices.size(); j++) {
boolean flag = true;
int k = i;
for (int l = indices.get(j); l >= k; l--, k++) {
if (list[k] != list[l]) {
flag = false;
break;
}
}
if (flag) {
int length = (indices.get(j) - i) + 1;
if (length != 1 && length > output) {
output = length;
}
}
}
}
return output;
}
public static ArrayList<Integer> getIndices(int[] list, int start, int num) {
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i = start + 1; i < list.length; i++) {
if (list[i] == num) {
result.add(i);
}
}
return result;
}
}
I need to return the greatest negative value, and if there are no negative values, I need to return zero.
Here is what I have:
public int greatestNegative(int[] list) {
for (int i = 0; i < list.length; i++) {
if (list[i] < 0)
negativeNumbers ++;
}
int j = list.length - 1;
while (j >= 0) {
if (list[j - negativeNumbers] < 0) {
list[j] = 0;
list[j - 1] = list[j - negativeNumbers];
negativeNumbers--;
j--;
}
else{
list[j] = list[j - negativeNumbers];
j--;
}
}
}
You just need to think of this problem as 2 steps:
Only consider negative values in list[].
In the loop within negative values, update current result if (result == 0) or (value > result).
Code:
public int greatestNegative(int[] list) {
int result = 0;
for (int i = 0; i < list.length; i++) {
if (list[i] < 0) {
if (result == 0 || list[i] > result) {
result = list[i];
}
}
}
return result;
}
Just go about finding the max number with an added condition.
public static int greatestNegative(int[] list) {
int max = Integer.MIN;
boolean set = false;
for (int i = 0; i < list.length; i++) {
if (list[i] < 0 && list[i] > max) {
max = arr[i];
set = true;
}
}
if (!set)
max = 0;
return max;
}
Here is the code which return the smallest negative number
public static int greatestNegative(int[] list) {
int negativeNumbers = 0;
for (int i = 0; i < list.length; i++) {
if (list[i] < 0 && list[i] < negativeNumbers)
negativeNumbers = list[i];
}
return negativeNumbers;
}
Input : 1, 2, -3, 5, 0, -6
Output : -6
Input : 1, 2, 3, 5, 0, 6
Output : 0
If you need the greatest negative number then sort array thin search for first negative number
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int arr[] = { 2, 4, 1, 7,2,-3,5,-20,-4,5,-9};
System.out.println(greatestNegative(arr));
}
private static int greatestNegative(int[] arr) {
Arrays.sort(arr);
for (int i = arr.length - 1; i >= 0; i--) {
if (isNegative (arr[i])) {
return arr[i];
}
}
return 0;
}
private static boolean isNegative (int i) {
return i < 0;
}
}
Output : -3
Please check following code, which will
first calculate small number from array,
then check is it positive? if yes return 0 else return negative.
public static int greatestNegative(int[] list)
{
int negativeNumbers = Integer.MAX_VALUE;
for (int i = 0; i < list.length; i++) {
if (list[i] < negativeNumbers)
negativeNumbers = list[i];
}
if(negativeNumbers >=0)
return 0;
else
return negativeNumbers;
}
You have to try this....
public int greatestNegative(int[] list) {
int negNum = 0;
for(int i=0; i<list.length; i++) {
if(list[i] < negNum){
negNum = list[i];
}
}
return negNum;
}
public int largNegative(int[] list) {
int negNum = 0;
boolean foundNeg = false;
for(int i=0; i<list.length; i++) {
if(list[i] < negNum && !foundNeg){
foundNeg = true;
negNum = list[i];
} else if(foundNeg && list[i] < 0 && negNum < list[i]) {
negNum = list[i];
}
}
return negNum;
}
Start by setting your "maxNegative" value to 0. Then assign the first negative number you come across. After that, only assign negative numbers that are higher. If there are no negative numbers, then your "maxNegative" will still be zero.
public static void main(String[] args) {
int arr[] = {2, -1, 4, 1, 0, 7, 2, -3, 5, 9, -4, 5, -9};
int maxNegative = 0;
for (int i = 0; i < arr.length; i++) {
if (maxNegative == 0 && arr[i] < maxNegative) {
// Set the first negative number you come across
maxNegative = arr[i];
} else if (maxNegative < arr[i] && arr[i] < 0) {
// Set greater negative numbers
maxNegative = arr[i];
}
}
System.out.println(maxNegative);
}
Results:
-1
Java 8
Then there are streams, that allow you to do this with one line of code.
public static void main(String[] args) {
int arr[] = {2, 4, 1, 0, 7, 2, -3, 5, 9, -4, 5, -9};
int maxNegative = Arrays.stream(arr).filter(a -> a < 0).max().orElse(0);
System.out.println(maxNegative);
}
Results:
-3
I am writing a JAVA code to generate all permutations of a integer array.
Though I am getting the number of permutations right, the permutations themselves are not correct.
On running I obtain:
Input array Length
3
1
2
3
0Permutation is
1, 2, 3,
##########################
1Permutation is
1, 3, 2,
##########################
2Permutation is
3, 1, 2,
##########################
3Permutation is
3, 2, 1,
##########################
4Permutation is
1, 2, 3,
##########################
5Permutation is
1, 3, 2,
##########################
6 number of permutations obtained
BUILD SUCCESSFUL (total time: 3 seconds)
public class PermulteArray {
public static int counter = 0;
public static void Permute(int[] input, int startindex) {
int size = input.length;
if (size == startindex + 1) {
System.out.println(counter + "Permutation is");
for (int i = 0; i < size; i++) {
System.out.print(input[i] + ", ");
}
System.out.println();
System.out.println("##########################");
counter++;
} else {
for (int i = startindex; i < size; i++) {
int temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
Permute(input, startindex + 1);
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Input array Length");
int arraylength = in.nextInt();
int[] input = new int[arraylength];
for (int i = 0; i < arraylength; i++) {
input[i] = in.nextInt();
}
counter = 0;
Permute(input, 0);
System.out.println(counter + " number of permutations obtained");
}
}
int temp=input[i];
input[i]=input[startindex];
input[startindex]=temp;
Permute(input, startindex+1);
You've swapped an element before calling Permute but you need to swap it back again afterwards to keep consistent positions of elements across iterations of the for-loop.
This is the best solution I have seen so far :
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6 };
permute(0, a);
}
public static void permute(int start, int[] input) {
if (start == input.length) {
//System.out.println(input);
for (int x : input) {
System.out.print(x);
}
System.out.println("");
return;
}
for (int i = start; i < input.length; i++) {
// swapping
int temp = input[i];
input[i] = input[start];
input[start] = temp;
// swap(input[i], input[start]);
permute(start + 1, input);
// swap(input[i],input[start]);
int temp2 = input[i];
input[i] = input[start];
input[start] = temp2;
}
}
check this out
for (int i = startindex; i < input2.length; i++) {
char[] input = input2.clone();
char temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
permute(input, startindex + 1);
}
//This will give correct output
import java.util.Scanner;
public class PermulteArray {
public static int counter = 0;
public static void Permute(int[] input, int startindex) {
int size = input.length;
if (size == startindex + 1) {
System.out.println(counter + "Permutation is");
for (int i = 0; i < size; i++) {
System.out.print(input[i] + ", ");
}
System.out.println();
System.out.println("##########################");
counter++;
} else {
for (int i = startindex; i < size; i++) {
int temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
Permute(input, startindex + 1);
temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Input array Length");
int arraylength = in.nextInt();
int[] input = new int[arraylength];
for (int i = 0; i < arraylength; i++) {
input[i] = in.nextInt();
}
counter = 0;
Permute(input, 0);
System.out.println(counter + " number of permutations obtained");
}
}
You can solve this using recursive calls.
https://github.com/Pratiyush/Master/blob/master/Algorithm%20Tutorial/src/arrays/Permutations.java
public void swap(int[] arr, int i, int j)
{
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public void permute(int[] arr, int i)
{
if (i == arr.length)
{
System.out.println(Arrays.toString(arr));
return;
}
for (int j = i; j < arr.length; j++)
{
swap(arr, i, j);
permute(arr, i + 1); // recurse call
swap(arr, i, j); // backtracking
}
}
public static void main(String[] args) {
Permutations permutations = new Permutations();
int[] arr = {1, 2, 3,4};
permutations.permute(arr, 0);
}
Also, other approaches are available in
http://www.programcreek.com/2013/02/leetcode-permutations-java/
http://www.programcreek.com/2013/02/leetcode-permutations-ii-java/
public class PermuteArray {
public static void permute(char[] input2, int startindex) {
if (input2.length == startindex) {
displayArray(input2);
} else {
for (int i = startindex; i < input2.length; i++) {
char[] input = input2.clone();
char temp = input[i];
input[i] = input[startindex];
input[startindex] = temp;
permute(input, startindex + 1);
}
}
}
private static void displayArray(char[] input) {
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + "; ");
}
System.out.println();
}
public static void main(String[] args) {
char[] input = { 'a', 'b', 'c', 'd'};
permute(input, 0);
}
}
import java.util.ArrayList;
public class RecursivePermGen {
void permGen(int n, int m, ArrayList<Integer> cur) {
if(m == 0) {
System.out.println(cur);
return;
}
for(int i = 1; i <= n; i++) {
cur.add(0, i);
permGen(n, m-1, cur);
cur.remove(0);
}
}
public static void main(String[] args) {
RecursivePermGen pg = new RecursivePermGen();
ArrayList<Integer> cur = new ArrayList<Integer>();
pg.permGen(2, 2, cur);
}
}
I have simple answer for this question, you can try with this.
public class PermutationOfString {
public static void main(String[] args) {
permutation("123");
}
private static void permutation(String string) {
printPermutation(string, "");
}
private static void printPermutation(String string, String permutation) {
if (string.length() == 0) {
System.out.println(permutation);
return;
}
for (int i = 0; i < string.length(); i++) {
char toAppendToPermutation = string.charAt(i);
String remaining = string.substring(0, i) + string.substring(i + 1);
printPermutation(remaining, permutation + toAppendToPermutation);
}
}
}
A solution i have used several times (mostly for testing purposes) is in the following gist. It is based on the well-known algorithm to generate permutations in lexicographic order (no recursion):
/**
* Compute next (in lexicographic order) permutation and advance to it.
*
* Find greater index i for which a j exists, such that:
* j > i and a[i] < a[j] (i.e. the 1st non-inversion).
* For those j satisfying the above, we pick the greatest.
* The next permutation is provided by swapping
* items at i,j and reversing the range a[i+1..n]
*/
void advanceToNext() {
// The array `current` is the permutation we start from
// Find i when 1st non-inversion happens
int i = n - 2;
while (i >= 0 && current[i] >= current[i + 1])
--i;
if (i < 0) {
// No next permutation exists (current is fully reversed)
current = null;
return;
}
// Find greater j for given i for 1st non-inversion
int j = n - 1;
while (current[j] <= current[i])
--j;
// Note: The range a[i+1..n] (after swap) is reverse sorted
swap(current, i, j); // swap current[i] <-> current[j]
reverse(current, i + 1, n); // reverse range [i+1..n]
}
A complete solution (in the form of a class) lies here:
https://gist.github.com/drmalex07/345339117fef6ca47ca97add4175011f