Two Sum II - Input array is sorted - java

Leetcode #167 is almost same as #1, but why I cannot only add a if condition?
Q: Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.
Note:
Your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution and you may not use the same element twice.
Example:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
The sum of 2 and 7 is 9.
Therefore index1 = 1, index2 = 2.
My code:
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 1; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] == target - numbers[i]) {
if(numbers[i] < numbers[j])
return new int[] { i, j };
}
}
}
return null;
}
}
Why I always return null? where is my mistake? How to fix it?

Because the question says array starts from 1 does not mean array starts from 1 in java.If you want to return i,j as non-zero you should go from 1 to length+1 and then inside the conditions you should check indexes as i-1,j-1 or just start from 0 and return i+1,j+1.
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 1; i < numbers.length+1; i++) {
for (int j = i + 1; j < numbers.length+1; j++) {
if (numbers[j-1] == target - numbers[i-1]) {
if(numbers[i-1] < numbers[j-1])
return new int[] { i, j };
}
}
}
return null;
}
}
or you can do,
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] == target - numbers[i]) {
if(numbers[i] < numbers[j])
return new int[] { i+1, j+1 };
}
}
}
return null;
}
}

https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/
[question]: 167. Two Sum II - Input array is sorted
Using the two-pointer technique:-
class Solution {
public int[] twoSum(int[] numbers, int target) {
if (numbers == null || numbers.length == 0)
return null;
int i = 0;
int j = numbers.length - 1;
while (i < j) {
int x = numbers[i] + numbers[j];
if (x < target) {
++i;
} else if (x > target) {
j--;
} else {
return new int[] { i + 1, j + 1 };
}
}
return null;
}
}

I have modified your code and added code comments on why your previous code has errors. Refer to code below for details.
public class Main {
public static void main(String[] args) {
int target = 9;
int[] numbers = new int[] { 2, 7, 11, 15 };
int[] result = twoSum(numbers, target);
if (result != null) {
System.out
.println("The sum of " + numbers[result[0]] + " and " + numbers[result[1]] + " is " + target + ".");
System.out.println("Therefore index1 = " + (result[0] + 1) + ", index2 = " + (result[1] + 1));
} else {
System.out.println("No Solution found!");
}
}
public static int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; i++) { // array index starts at 0
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[j] + numbers[i] == target) { // add the current numbers
// if (numbers[i] < numbers[j]) // not needed
return new int[] { i, j };
}
}
}
return null;
}
}
Sample input:
numbers = [2, 7, 11, 15];
Sample output:
The sum of 2 and 7 is 9.
Therefore index1 = 1, index2 = 2

You are starting first for-loop with i = 0, what you should do is start it with i = 1.
Working code:
public class Solution
{
public static void main(String[] args)
{
int[] num = {2,7,11,5};
int n = 13;
int[] answer = new int[2];
answer = twoSum(num,n);
if(answer != null)
for(int i=0;i<2;i++)
System.out.printf( answer[i] +" ");
}
public static int[] twoSum(int[] numbers, int target)
{
for (int i = 0; i < numbers.length; i++)
{
for (int j = i + 1; j < numbers.length; j++)
{
if (numbers[j] == target - numbers[i])
{
if(numbers[i] < numbers[j])
return new int[] { i+1, j+1};
}
}
}
return null;
}
}
Note: I have placed an IF before FOR in main() so that if we find no such integers that adds up to give target integer, it'll not throw a NullPointerException.

This is a better solution as it's much faster and covers all test cases as well:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l = 0, r = numbers.length - 1;
while (numbers[l] + numbers[r] != target) {
if (numbers[l] + numbers[r] > target)
r--;
else
l++;
if (r == l) return new int[]{};
}
return new int[]{l + 1, r + 1};
}
}

public int[] twoSum(int[] nums, int target) {
int start = 0, end = nums.length -1;
while (start < end){
if (nums[start]+ nums[end]== target)
return new int []{start+1, end+1};
if (nums[start]+ nums[end]> target){
end--;}
else if (nums[start]+ nums[end]< target){
start++;
}
}
return null;
}

Related

add twoNumber in the array and must equal target

I have this program where the number of elements of the array "n" is entered and then the target is entered "d",
Then I want to add two numbers from the matrix and the addition is equal to target "d",
Then I want to return an array of Indexes of these two numbers
Example:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
I wrote this program, but I could not return the Indexes,
How can I solve the problem?
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
System.out.println("This the number that we want it" + "\n" + i + "\n" + j);
}
}
}
return nums;
}
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
res[0] = i;
res[1] = j;
System.out.println("This the number that we want it" + "\n" + i + "\n" + j);
}
}
}
return res;
}
You need to create a new array of size 2 and return that.
If you are happy with O(n^2) complexity, you don't need to read ahead. But here is a solution with O(n) time complexity:
public int[] twoSum(int[] numbers, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < numbers.length; map.put(numbers[i], ++i)) {
if (map.containsKey(target - numbers[i])) {
return new int[] {map.get(target - numbers[i]), i + 1};
}
}
return new int[]{0,0};
}
Look at this solutions!
Time complexity O(n^2), space complexity O(1)
public static int[] foo(int[] arr, int d) {
for (int i = 0; i < arr.length - 1; i++)
for (int j = i + 1; j < arr.length; j++)
if (arr[i] + arr[j] == d)
return new int[] { i, j };
return new int[] {-1, -1};
}
Time complexity O(n), space complexity O(n)
public static int[] foo(int[] arr, int d) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(d - arr[i]))
return new int[] { map.get(d - arr[i]), i };
map.put(arr[i], i);
}
return new int[] {-1, -1};
}

Counting number of duplicates in a given array

Input: 1,4,2,6,7,5,1,2
Output:2
Counting the number of duplicated numbers in a given array for java. I first sorted the array and then counted duplicates. It's showing me error that variable c is not used and that this method should return value of int.
public class Duplicates
public static void main(String[] args) {
int[]list;
int[]c;
int[] c = new int[list.length];
int temp;
for (int i = 0; i < list.length - 1; i++) {
for (int j = i + 1; j < list; j++) {
if (list[I] > list[j]) {
temp = list[i];
list[i] = list[j];
list[j] = temp;
c = list;
}
}
}
int n = 0;
int counter = 0;
int a = -1;
for (int i = 0; i < c.length; ++i) {
if (c[i] == a) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(c[i]);
} else {
System.out.print("," + c[i]);
}
}
} else {
a = c[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array:" + counter);
}
}
It's showing me error that variable c is not used
This should be a warning. So the code should still run correctly even with this is showing.
this method should return value of int
This is a compilation error and since you are not returning any int array at the end of the method, your method's return type should be void. You should change your method signature as below,
public static void c(int[] list)
Otherwise you will need to return an int array at the end of your method.
After fixing your code,
public class Duplicates {
public static void main(String[] args) {
int[] list = new int[]{1, 4, 2, 6, 7, 5, 1, 2};
int temp;
for (int i = 0; i < list.length; ++i) {
for (int j = 1; j < (list.length - i); ++j) {
if (list[j - 1] > list[j]) {
temp = list[j - 1];
list[j - 1] = list[j];
list[j] = temp;
}
}
}
int n = 0, counter = 0;
int previous = -1;
for (int i = 0; i < list.length; ++i) {
if (list[i] == previous) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(list[i]);
} else {
System.out.print(", " + list[i]);
}
}
} else {
previous = list[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array: " + counter);
}
}

Searching for a sum in an array

I have a method which counts how many sums of 3 elements,which are equal to 0, does the array contains. I need help finding the way to stop counting the same triplets in the loop. For instance, 1 + 3 - 4 = 0, but also 3 - 4 +1 = 0.Here is the method:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if(binarySearch(A,sum))
{
count++;
}
}
}
return count;
edit: I have to use the Binary Search (the array is sorted).
Here is the binarySearch code:
private static boolean binarySearch(int A[],int y)
{
y=-y;
int max = A.length-1;
int min = 0;
int mid;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
return true;
}
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
return false;
You can avoid counting different triplets by making one assumption that we need to look for the triplets (x,y,z) with x < y < z and A[x] + A[y] + A[z] == 0.
So what you need to do is to modify the binarySearch function to return the number of index that greater than y and has A[z] == -(A[x] + A[y])
private static int binarySearch(int A[],int y, int index)
{
y=-y;
int max = A.length-1;
int min = index + 1;
int mid;
int start = A.length;
int end = 0;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
start = Math.min(start, mid);
max = mid - 1;
} else
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
int max = A.length - 1;
int min = index + 1;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
end = Math.max(end, mid);
min= mid + 1;
} else if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
if(start <= end)
return end - start + 1;
return 0;
}
So the new function binarySearch will return the total number of index that greater than index and has value equals to y.
So the rest of the job is to count the answer
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
count += binarySearch(A,sum, j);
}
}
return count;
}
Notice how I used two binary search to find the starting and the ending index of all values greater than y!
private static int counter(int A[]) {
int e = A.length;
int count = 0;
for (int i = 0; i < e; i++) {
for (int j = 1; (j < e - 1) && (i != j); j++) {
for (int k = 2; (k < e - 2) && (j != k); k++) {
if (A[i] + A[j] + A[k] == 0) {
count++;
}
}
}
}
return count;
}
private static int counter(int ints[]) {
int count = 0;
for (int i = 0; i < ints.length; i++) {
for (int j = 0; j < ints.length; j++) {
if (i == j) {
// cannot sum with itself.
continue;
}
for (int k = 0; k < ints.length; k++) {
if (k == j) {
// cannot sum with itself.
continue;
}
if ((ints[i] + ints[j] + ints[k]) == 0) {
count++;
}
}
}
}
return count;
}
To solve problem with binary search
Your code was almost correct. all you needed to do was just to replace
if (sum == binarySearch(A,sum)) {
with this
if (binarySearch(A,sum)) {
I am assuming that your binarySearch(A, sum) method will return true if it will found sum in A array else false
private static int counter(int A[]) {
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++) {
for (int j=i+1; j<e; j++) {
sum=A[i]+A[j];
if (binarySearch(A,sum)) {
count++;
}
}
}
return count;
}
Here is my solution assuming the array is sorted and there are no repeated elements, I used the binary search function you provided. Could the input array contain repeated elements? Could you provide some test cases?
In order to not counting the same triplets in the loop, we should have a way of inspecting repeated elements, the main idea that I used here is to have a list of int[] arrays saving the sorted integers of {A[i],A[j],-sum}.Then in each iteration I compare new A[i] and A[j] to the records in the list, thus eliminating repeated ones.
private static int counter(int A[]){
int sum;
int e = A.length;
int count = 0;
List<int[]> elements = new ArrayList<>();
boolean mark = false;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if (-sum == binarySearch(A,sum)){
int[] sort = {A[i],A[j],-sum};
if(-sum == A[i] || -sum == A[j]){
continue;
}else{
Arrays.sort(sort);
//System.out.println("sort" + sort[0] + " " + sort[1]+ " " + sort[2]);
for (int[] element : elements) {
if((element[0] == sort[0] && element[1] == sort[1]) && element[2] == sort[2])
mark = true;
}
if(mark){
mark = false;
continue;
}else{
count++;
elements.add(sort);
//System.out.println("Else sort" + sort[0] + " " + sort[1]);
}
}
}
}
}
return count;
}
you can use a assisted Array,stored the flag that indicate if the element is used;
Here is the code:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
// assisted flag array
List<Boolean> flagList = new ArrayList<Boolean>(e);
for (int k = 0; k < e; k++) {
flagList.add(k, false);// initialization
}
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
// if element used, no count
if(binarySearch(A,sum)&& !flagList.get(i)&& !flagList.get(j))
{
count++;
flagList.set(i, true);
flagList.set(j, true);
}
}
}
return count;

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.

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