Java Comparison of If/While Loop - java

Working on a leetcode problem described as: "Given a binary array nums and an integer k, return the maximum number of consecutive 1's in the array if you can flip at most k 0's."
I am using a sliding window approach and had produced the below code:
class Solution {
public int longestOnes(int[] nums, int k) {
int current = 0;
int left = 0;
int ans = 0;
for (int right = 0; right < nums.length; right++){
if (nums[right] == 0){
current++;
}
while (current > k){
if (nums[left] == 0){
current--;
}
left++;
}
ans = right - left + 1;
}
return ans;
}
}
This produces a logical error in the ouptut where the value returned is off by 1 in either direction depending on the test. I replaced the while loop with in if statement shown in the code below which fixed the error. Why is this the case?
class Solution {
public int longestOnes(int[] nums, int k) {
int current = 0;
int left = 0;
int ans = 0;
for (int right = 0; right < nums.length; right++){
if (nums[right] == 0){
current++;
}
if (current > k){
if (nums[left] == 0){
current--;
}
left++;
}
ans = right - left + 1;
}
return ans;
}
}
I expected the while loop to run once and be equivalent as the block should evaluate the condition on each iteration and then act if the condition is true. What is happening here?

Solution moved from #SiggyWeb's question post:
Solution found via feedback from the comments
class Solution {
public int longestOnes(int[] nums, int k) {
int current = 0;
int left = 0;
int ans = 0;
for (int right = 0; right < nums.length; right++){
if (nums[right] == 0){
current++;
}
while (current > k){
if (nums[left] == 0){
current--;
}
left++;
}
ans = Math.max(ans,right - left + 1);
}
return ans;
}
}

Related

Implementing my own pow function in Java

This is a popular interview question. Implementing my own pow function.
There are some popular recursive approaches available online but I'm trying to do it iteratively. The code works for n > 0, but I'm a little lost when it gets below 0. Here's my code.
public double myPow(double x, int n) {
if(x == 0) return 0;
if(n == 0) return 1;
double result = 1;
if(n > 0 ){
for(int i=1; i <= n; i++){
result = result * x;
}
}else{
for(int i=1; i<= n; i++){
//calculate the nth root
}
}
return result;
}
Any help appreciated with calculating the nth root.
I guess you can do that: (because x^(-n) = 1/x^n)
double positive_pow(double x, int n) {
if(x == 0) return 0;
if(n == 0) return 1;
double result = 1;
if(n > 0 ){
for(int i=1; i <= n; i++){
result = result * x;
}
}else{
for(int i=1; i<= n; i++){
//calculate the nth root
}
}
return result;
}
public double pow(double x, int n) {
if (n > 0) return positive_pow(x, n);
else if (n == 0) return 1;
else return 1 / positive_pow(x, 0-n);
}
This is not the shortest way to implement this, but it is based on your base function and it's more clear than recursively calculating it or messing around with Math functions.
This will work.
This code will be returning result for negative powers as well. For the explanation I have used the variable int p= x for my calculation of negative powers.....
public static double Pow(int x,int n){
if(x == 0) return 0;
if(n == 0) return 1;
double result = 1;
if(n > 0 ){
for(int i=1; i <= n; i++){
result = result * x;
}
}
else{
int p=x;
for(int i=0; i>n; i--){
if(result==1){
result= 1/(result*x);
result++;
}
else{
p=p*x;
result= (1.0)*1/p;
}
}
}
return result;
}
Try this, I wrote this one when I was practicing Java. The idea is 5^62=5^(32+16+8+4+2)=5^32*5^16*5^8*5^4*5^2, and in binary code, 62 is 00111110.
Here is the code:
double pow(double x, int n){
int i;
double result;
result = 1;
i = x;
while(n != 0){
if(n & 1 == 1){
result *= i;
}
i *= i;
n>>1;
}
return result;
}

Count the number of checks each method had to perform before fully sorting the array

So I'm writing a program that compares Bubble, Selection, Merge, and Quick Sort. All 4 methods are given a randomized array of 1000 elements and I count to see how many times it takes a method to perform to fully sort the array. My question revolves around the placement of my counts. I know I should look at the Big O complexities for each to get a ballpark estimate of the number but I'm just asking if I put the counts in the right spots.
Bubble Sort:
public static int[] bubbleSort(int[] a)
{
boolean done = false;
int n = a.length;
while(done == false)//runs n times
{
done = true;
for(int i = 0; i < n-1; i++)//runs n times
{
if(a[i] > a[i+1])//Swap
{
bubbleCount++;
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
done = false;
}
}
}
return a;
}
Selection Sort:
public static void selectionSort(int[] a )
{
for (int i = 0; i < a.length - 1; i++)
{
int pos = i;
for (int j = i + 1; j < a.length; j++)
{
// increments selection count
selectionCount++;
// if a[j] is less than a[pos], set pos to j
if (a[j] < a[pos])
{
pos = j;
}
}
// swaps a[i] and a[pos]
int temp = a[i];
a[i] = a[pos];
a[pos] = temp;
}
}
Merge Sort:
public static void mergeSort(int [] a)
{
//put counter for checks inside method
int size = a.length;
if(size < 2)//Halt recursion
{
return;
}
int mid = size/ 2;
int leftSize = mid;
int rightSize = size - mid;
int[] left = new int[leftSize];
int[] right = new int[rightSize];
//populate left
for(int i = 0; i < mid; i++)
{
mergeCount++;
left[i] = a[i];
}
//populate right
for(int i = mid; i < size; i++)
{
mergeCount++;
right[i-mid] = a[i];
}
mergeSort(left);
mergeSort(right);
//merge
merge(left, right, a);
}
public static void merge(int[] left, int[] right, int[] a)
{
int leftSize = left.length;
int rightSize = right.length;
int i = 0;//index for left
int j = 0;//index for right
int k = 0;//index for a
while(i < leftSize && j < rightSize)//compares until the end is reach in either
{
if(left[i] <= right[j])
{
//assigns a[k] to left[i] and increments both i and k
a[k] = left[i];
i++;
k++;
}
else
{
//assigns a[k] to right [j] and increments j and k
a[k] = right[j];
j++;
k++;
}
}
//fills in the rest
while(i<leftSize)
{
a[k] = left[i];
i++;
k++;
}
while(j<rightSize)
{
a[k] = right[j];
j++;
k++;
}
}
Quick Sort
public static void quickSort(int[] a, int left, int right)
{
int index = partition(a, left, right);
if(left < index - 1)
{
//increments quickCount and calls quickSort recursively
quickCount++;
quickSort(a, left, index-1);
}
if(index < right)
{
//increments quickCount and calls quicSort recursively
quickCount++;
quickSort(a, index, right);
}
}
public static int partition(int[] a, int left, int right)
{
int i = left;
int j = right;
int pivot = a[((left+right)/2)];
while(i<=j)
{
while(a[i] < pivot)
{
i++;//correct position so move forward
}
while(a[j] > pivot)
{
j--;//correct position
}
if(i <= j)
{
//swaps and increments i and decrements j
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
return i;
}
Your counts should be wherever you do a comparison of two values.
The bubbleCount should be moved up above the if because you want to count every comparison not sure the ones where the if clause is true. The selectionCount seems okay. The mergeCount should be moved to where you compare values.
You need to count comparisons, so I would create a method to compare and count:
static int count;
private static boolean isGreaterThan(int i, int j) {
count++;
return i > j;
}
and always use that method to compare values:
instead of:
while(i<=j)
do:
while(!isGreaterThan(i, j))
etc

Need help count inversions with merge sort

The following code counts inversions in an array nums (pairs i,j such that j>i && nums[i] > nums[j]) by merge sort.
Is it possible to use the same approach to count the number of special inversions like j>i && nums[i] > 2*nums[j]?
How should I modify this code?
public static void main (String args[])
{
int[] nums = {9, 16, 1, 2, 3, 4, 5, 6};
System.out.println("Strong Inversions: " + countInv(nums));
}
public static int countInv(int nums[])
{
int mid = nums.length/2;
int countL, countR, countMerge;
if(nums.length <= 1)
{
return 0;
}
int left[] = new int[mid];
int right[] = new int[nums.length - mid];
for(int i = 0; i < mid; i++)
{
left[i] = nums[i];
}
for(int i = 0; i < nums.length - mid; i++)
{
right[i] = nums[mid+i];
}
countL = countInv (left);
countR = countInv (right);
int mergedResult[] = new int[nums.length];
countMerge = mergeCount (left, right, mergedResult);
for(int i = 0; i < nums.length; i++)
{
nums[i] = mergedResult[i];
}
return (countL + countR + countMerge);
}
public static int mergeCount (int left[], int right[], int merged[])
{
int a = 0, b = 0, counter = 0, index=0;
while ( ( a < left.length) && (b < right.length) )
{
if(left[a] <= right[b])
{
merged [index] = left[a++];
}
else
{
merged [index] = right[b++];
counter += left.length - a;
}
index++;
}
if(a == left.length)
{
for (int i = b; i < right.length; i++)
{
merged [index++] = right[i];
}
}
else
{
for (int i = a; i < left.length; i++)
{
merged [index++] = left[i];
}
}
return counter;
}
I tried this
while ((a < left.length) && (b < right.length)) {
if (left[a] <= right[b]) {
merged[index] = left[a++];
} else {
if (left[a] > 2 * right[b]) {
counter += left.length - a;
}
merged[index] = right[b++];
}
index++;
}
but there's a bug in the while loop, when left[a]<2*right[b] but left[a+n] maybe>2*right[b], for instance left array is {9,16} and right array is {5,6}, 9<2*5 but 16>2*5. My code just skip cases like this and the result number is less than it should be
The while loop in mergeCount serves two functions: merge left and right into merged, and count the number of left–right inversions. For special inversions, the easiest thing would be to split the loop into two, counting the inversions first and then merging. The new trigger for counting inversions would be left[a] > 2*right[b].
The reason for having two loops is that counting special inversions needs to merge left with 2*right, and sorting needs to merge left with right. It might be possible to use three different indexes in a single loop, but the logic would be more complicated.
while ( ( a < left.length) && (b < right.length) ) {
if(left[a] <= right[b]) {
merged [index] = left[a++];
} else {
counter += updateCounter(right[b],a,left);
merged [index] = right[b++];
}
index++;
//Rest of the while loop
}
//Rest of the mergeCount function
}
public static int updateCounter(int toSwitch, int index, int[] array) {
while(index < array.length) {
if(array[index] >= 2*toSwitch)
break;
index++;
}
return array.length-index;
}
Not very efficient, but it should do the work. You initialise index with a, because elements lower than a will never will never meet the condition.

in quicksort why do we start the decrement outside the array

public class QuickSort {
public static void sort(int[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
}
private static void sort(int[] a, int left, int right) {
if (right <= left) {
return;
}
int j = partition(a, left, right);
sort(a, left, j - 1);
sort(a, j + 1, right);
}
private static int partition(int[] a, int left, int right) {
int i = left;
int j = right+1;
int pivot = a[left];
while (true) {
while (a[++i] < pivot) {
if (i == right) {
break;
}
}
while (a[--j] > pivot) {
if (j == left) {
break;
}
}
if (i >= j) {
break;
}
swap(a, i, j);
}
swap(a, left, j);
return j;
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int[] a = { 5, 3, 1, 34, 43, 5454};
QuickSort.sort(a);
show(a);
}
private static void show(int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
}
in this example, the int j = right+1 starts outside the array, so then we decrement by a[--j]
When I change it to int j = right and decrement by a[j--] the output is not the same. Probably something simple but been confused about for the past hour. I don't get why we don't just decrement starting at the last index of the array such as:
{4,3,6,1,9}
int j = right
so j = array[4] then we say while... array[4--] which would turn into j=array[3] right?
isn't this the same thing: right+1 and --j and to right and j--
The lines:
while (a[--j] > pivot) {
if (j == left) {
break;
}
}
Expect the two values of j to be the same. If you change it to
while (a[j--] > pivot) {
if (j == left) {
break;
}
}
The first referenced j, a[j--] will be one higher then the next j, j == left
If you wanted to make the change, you would have to change it to:
while (a[j--] > pivot) {
if (j+1 == left) { //adding one back in
break;
}
}
My personal opinion is that the code was cleaner before, since starting one outside a range is common and understandable. Adding one back is is 'fiddly' and will make everyone question whether it is correct.
The clearest way to make your change might be:
while (a[j] > pivot) {
if (j == left) {
break;
}
j--; // waiting until the end to decrement
}
I would consider that pretty clean, and preferable to the original because you start with int j = right.
The value of j is compared against in other places in the loop. If the counter started with j = right, after decrementing j with either --j or j-- the value of j at those points will not be the same as if you started with j = right+1

Find the largest span between the same number in an array

Merry Christmas and hope you are in great Spirits,I have a Question in Java-Arrays as shown below.Im stuck up with this struggling to get it rite.
Consider the leftmost and righmost appearances of some value in an array. We'll say that the "span" is the number of elements between the two inclusive. A single value has a span of 1. Write a **Java Function** that returns the largest span found in the given array.
**Example:
maxSpan({1, 2, 1, 1, 3}) → 4,answer is 4 coz MaxSpan between 1 to 1 is 4
maxSpan({1, 4, 2, 1, 4, 1, 4}) → 6,answer is 6 coz MaxSpan between 4 to 4 is 6
maxSpan({1, 4, 2, 1, 4, 4, 4}) → 6,answer is 6 coz Maxspan between 4 to 4 is 6 which is greater than MaxSpan between 1 and 1 which is 4,Hence 6>4 answer is 6.
I have the code which is not working,it includes all the Spans for a given element,im unable to find the MaxSpan for a given element.
Please help me out.
Results of the above Program are as shown below
Expected This Run
maxSpan({1, 2, 1, 1, 3}) → 4 5 X
maxSpan({1, 4, 2, 1, 4, 1, 4}) → 6 8 X
maxSpan({1, 4, 2, 1, 4, 4, 4}) → 6 9 X
maxSpan({3, 3, 3}) → 3 5 X
maxSpan({3, 9, 3}) → 3 3 OK
maxSpan({3, 9, 9}) → 2 3 X
maxSpan({3, 9}) → 1 1 OK
maxSpan({3, 3}) → 2 3 X
maxSpan({}) → 0 1 X
maxSpan({1}) → 1 1 OK
::Code::
public int maxSpan(int[] nums) {
int count=1;//keep an intial count of maxspan=1
int maxspan=0;//initialize maxspan=0
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i] == nums[j]){
//check to see if "i" index contents == "j" index contents
count++; //increment count
maxspan=count; //make maxspan as your final count
int number = nums[i]; //number=actual number for maxspan
}
}
}
return maxspan+1; //return maxspan
}
Since a solution has been given, here is a more efficient solution which uses one pass.
public static void main(String... args) {
int maxspan = maxspan(3, 3, 3, 2, 1, 4, 3, 5, 3, 1, 1, 1, 1, 1);
System.out.println(maxspan);
}
private static int maxspan(int... ints) {
Map<Integer, Integer> first = new LinkedHashMap<Integer, Integer>(); // use TIntIntHashMap for efficiency.
int maxspan = 0; // max span so far.
for (int i = 0; i < ints.length; i++) {
int num = ints[i];
if (first.containsKey(num)) { // have we seen this number before?
int span = i - first.get(num) + 1; // num has been found so what is the span
if (span > maxspan) maxspan = span; // if the span is greater, update the maximum.
} else {
first.put(num, i); // first occurrence of number num at location i.
}
}
return maxspan;
}
I see the following problems with your attempt:
Your count is completely wrong. You can instead calculate count from i and j: j - i + 1
You're overriding maxcount as soon as you get any span, so you're going to end up with the last span, not the maximum span. Fix it by going maxspan = Math.max(maxspan, count);.
You can remove the line int number = nums[i]; as you never use number.
Remove the +1 in the returnmaxspan+1;` if you follow my tips above.
Initial maxspan should be 1 if there are any values in the array, but 0 if the array is empty.
That should help you get it working. Note that you can do this in a single pass of the array, but that's probably stretching it too far for you. Concentrate on getting your code to work before considering efficiency.
Here is the solution of this problem:
public int maxSpan(int[] nums) {
int maxSpan=0;
int tempSpan=0;
if(nums.length==0){
return 0;
}
for(int i=0;i<nums.length;i++){
for(int j=nums.length-1;j>i;j--){
if(nums[i]==nums[j]){
tempSpan=j-i;
break;
}
}
if(tempSpan>maxSpan){
maxSpan=tempSpan;
}
}
return maxSpan+1;
}
I did it with a List. Easier way to do it.
The only problem is if the Array is too big, maybe it's gonna take a while..
import java.util.ArrayList;
import java.util.List;
public class StackOverflow {
public static void main(String[] args) {
List<Integer> listNumbers = new ArrayList<Integer>();
listNumbers.add(3);
listNumbers.add(3);
listNumbers.add(3);
listNumbers.add(2);
listNumbers.add(1);
listNumbers.add(4);
listNumbers.add(3);
listNumbers.add(5);
listNumbers.add(1);
listNumbers.add(1);
listNumbers.add(1);
listNumbers.add(1);
listNumbers.add(1);
listNumbers.add(3);
int result = 0;
Integer key = null;
for(Integer i : listNumbers){
int resultDistance = returnDistance(listNumbers, i);
if (resultDistance > result){
result = resultDistance;
key = i;
}
}
System.out.println("MaxSpan of key " + key + " is: " + result);
}
private static int returnDistance(List<Integer> listNumbers, Integer term){
Integer startPosition = null;
Integer endPosition = null;
boolean bolStartPosition = false;
boolean bolResult = false;
int count = 1;
int result = 0;
for (Integer i : listNumbers){
if (i == term && !bolStartPosition){
startPosition = count;
bolStartPosition = true;
continue;
}
if (i == term && bolStartPosition){
endPosition = count;
}
count++;
}
if (endPosition != null){
// because it's inclusive from both sides
result = endPosition - startPosition + 2;
bolResult = true;
}
return (bolResult?result:-1);
}
}
public int maxSpan(int[] nums) {
int b = 0;
if (nums.length > 0) {
for (int i = 0; i < nums.length; i++) {
int a = nums[0];
if (nums[i] != a) {
b = nums.length - 1;
} else {
b = nums.length;
}
}
} else {
b = 0;
}
return b;
}
One brute force solution may like this, take one item from the array, and find the first occurance of item from the left most, and calculate the span, and then compare with the previous result.
public int maxSpan(int[] nums) {
int result = 0;
for(int i = 0; i < nums.length; i++) {
int item = nums[i];
int span = 0;
for(int j = 0; j<= i; j++) {//find first occurance of item from the left
if(nums[j]==item) {
span = i -j+1;
break;
}
}
if(span>result) {
result = span;
}
}
return result;
}
Here is the solution -
public int maxSpan(int[] nums) {
int span = 0;
for (int i = 0; i < nums.length; i++) {
for(int j = i; j < nums.length; j++) {
if(nums[i] == nums[j]) {
if(span < (j - i + 1)) {
span = j -i + 1;
}
}
}
}
return span;
}
public int maxSpan(int[] nums) {
int span = 0;
//Given the values at position i 0..length-1
//find the rightmost position of that value nums[i]
for (int i = 0; i < nums.length; i++) {
// find the rightmost of nums[i]
int j =nums.length -1;
while(nums[i]!=nums[j])
j--;
// j is at the rightmost posititon of nums[i]
span = Math.max(span,j-i+1);
}
return span;
}
public int maxSpan(int[] nums) {
//convert the numnber to a string
String numbers = "";
if (nums.length == 0)
return 0;
for(int ndx = 0; ndx < nums.length;ndx++){
numbers += nums[ndx];
}
//check beginning and end of string
int first = numbers.indexOf(numbers.charAt(0));
int last = numbers.lastIndexOf(numbers.charAt(0));
int max = last - first + 1;
int efirst = numbers.indexOf(numbers.charAt(numbers.length()-1));
int elast = numbers.lastIndexOf(numbers.charAt(numbers.length()-1));
int emax = elast - efirst + 1;
//return the max span.
return (max > emax)?max:emax;
}
public int maxSpan(int[] nums) {
int current = 0;
int currentcompare = 0;
int counter = 0;
int internalcounter = 0;
if(nums.length == 0)
return 0;
for(int i = 0; i < nums.length; i++) {
internalcounter = 0;
current = nums[i];
for(int x = i; x < nums.length; x++) {
currentcompare = nums[x];
if(current == currentcompare) {
internalcounter = x - i;
}
if(internalcounter > counter) {
counter = internalcounter;
}
}
}
return counter + 1;
}
public int maxSpan(int[] nums) {
if(nums.length<1){
return 0;
}
int compare=1;
for (int i=0; i<nums.length; i++){
for (int l=1; l<nums.length; l++){
if((nums[l]==nums[i])&&(Math.abs(l)-Math.abs(i))>=compare){
compare = Math.abs(l)-Math.abs(i)+1;
}
}
}
return compare;
}
public static int MaxSpan(int[] input1, int key)
{
int Span = 0;
int length = input1.length;
int i,j,k = 0;
int start = 0, end = 0 ;
k = key;
for (int l = 0; l < length; l++) {
if(input1[l] == k) { start = l;
System.out.println("\nStart = " + start);
break;
}
}
if(start == 0) { Span = 0; System.out.println("Key not found"); return Span;}
for (j = length-1; j> start; j--) {
if(input1[j] == k) { end = j;
System.out.println("\nEnd = " + end);
break;
}
}
Span = end - start;
System.out.println("\nStart = " + start + "End = " + end + "Span = " + Span);
return Span;
}
public int maxSpan(int[] nums) {
int length = nums.length;
if(length <= 0)
return 0;
int left = nums[0];
int rigth = nums[length - 1];
int value = 1;
//If these values are the same, then the max span is length
if(left == rigth)
return length;
// the last match is the largest span for any value
for(int x = 1; x < length - 1; x++)
{
if(nums[x] == left || nums[x] == rigth)
value = x + 1;
}
return value;
}
public int maxSpan(int[] nums) {
int count, largest=0;
for (int x=0; x< nums.length; x++)
{
for (int y=0; y< nums.length; y++)
{
if (nums[x]==nums[y])
{
count= y-x+1;
if (count > largest)
{
largest= count;
}
}
}
}
return largest;
}
import java.io.*;
public class maxspan {
public static void main(String args[])throws java.io.IOException{
int A[],span=0,pos=0;
DataInputStream in=new DataInputStream(System.in);
System.out.println("enter the number of elements");
A=new int[Integer.parseInt(in.readLine())];
int i,j;
for(i=0;i<A.length;i++)
{
A[i]=Integer.parseInt(in.readLine());
}
for(i=0;i<A.length;i++)
{
for(j=A.length-1;j>=0;j--)
if(A[i]==A[j]&&(j-i)>span){span=j-i;pos=i;}
}
System.out.println("maximum span => "+(span+1)+" that is of "+A[pos]);
}
}
public static int maxSpan(int[] nums) {
int left = 0;
int right = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[0] == nums[nums.length - 1 - i]) {
left = nums.length - i;
break;
} else if (nums[nums.length - 1] == nums[i]) {
right = nums.length - i;
break;
}
}
return Math.max(left, right);
}
The above solutions are great, if your goal is to avoid using Arrays.asList and indexOf and LastIndexOf, the code below does the job as lazy as possible, while still being clear and concise.
public int maxSpan(int[] nums) {
if(nums.length < 2){ //weed out length 0 and 1 cases
return nums.length;
}
int maxSpan = 1; //start out as 1
for(int a = 0; a < nums.length; a++){
for(int b = nums.length - 1; b > a; b--){
if(nums[a] == nums[b]){
maxSpan = Math.max(maxSpan, (b + 1 - a));
//A little tricky getting those indices together.
break; //there's no reason to continue,
//at least for this single loop execution inside another loop
}
}
}
return maxSpan; //the maxSpan is here!
}
The Math.max method returns the larger of 2 values, one of them if they are equal.
This is how I did it:
public int maxSpan(int[] nums) {
for (int span=nums.length; span>0; span--) {
for (int i=0; i<nums.length-span+1; i++) {
if (nums[i] == nums[i+span-1]) return span;
}
}
return 0;
}
I am not sure, if I have to use 2 for-loops... or any loop at all?
If not, this version functions without any loop.
At first you check, if the length of the array is > 0. If not, you simply return the length of the array, which will correspond to the correct answer.
If it is longer than 0, you check if the first and last position in the array have the same value.
If yes, you return the length of the array as the maxSpan.
If not, you substract a 1, since the value appears twice in the array.
Done.
public int maxSpan(int[] nums) {
if(nums.length > 0){
if(nums[0] == nums[nums.length - 1]){
return nums.length;
}
else{
return nums.length - 1;
}
}
return nums.length;
}
public int maxSpan(int[] nums) {
Stack stack = new Stack();
int count = 1;
int value = 0;
int temp = 0;
if(nums.length < 1) {
return value;
}
for(int i = 0; i < nums.length; i++) {
for(int j = nums.length - 1; j >= i; j--) {
if(nums[i] == nums[j]) {
count = (j - i) + 1;
stack.push(count);
count = 1;
break;
}
}
}
if(stack.peek() != null) {
while(stack.size() != 0) {
temp = (Integer) stack.pop();
if(value <= temp) {
value = temp;
} else {
value = value;
}
}
}
return value;
}
public int maxSpan(int[] nums) {
int totalspan=0;
int span=0;
for(int i=0;i<nums.length;i++)
{
for (int j=nums.length-1;j>i-1;j--)
{
if(nums[i]==nums[j])
{
span=j-i+1;
if (span>totalspan)
totalspan=span;
break;
}
}
}
return totalspan;
}
public int maxSpan(int[] nums) {
int max_span=0, j;
for (int i=0; i<nums.length; i++){
j=nums.length-1;
while(nums[i]!=nums[j]) j--;
if (j-i+1>max_span) max_span=j-i+1;
}
return max_span;
}
Linear solution with a Map storing the first occurrence, and calculating the distance from it for the next occurrences:
public int maxSpan(int[] nums) {
int span = 0;
Map<Integer, Integer> first = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
if (!first.containsKey(nums[i]))
first.put(nums[i], i);
span = Math.max(span, (i - first.get(nums[i])) + 1);
}
return span;
}

Categories

Resources