Two Sum
Question:
Similar to Question [1. Two Sum], except that the input array is already sorted in ascending order.
Difficulty: Medium, Frequency: N/A
My solution
O(n log n) runtime, O(1) space – Binary search:
public int[] twoSum(int[] nums, int target) {
int[] ret = {-1, -1};
for(int i = 0; i < nums.length; i++){
int ind2 = binarySearch(nums, target-nums[i], i+1);//should be i+1, not i!!
if(ind2 != -1){
ret[0] = i+1;
ret[1] = ind2+1;
System.out.println("index1="+ret[0]+", index2="+ret[1]);
return ret;
}
}
throw new IllegalArgumentException("No valid two numbers match.");
}
private int binarySearch(int[] A, int t, int start){
int L = start, R = A.length-1;
while(L < R){
int M = (L + R) / 2;
if(A[L] < t) L = M + 1;
else R = M;
}
return (L == R && t == A[L]) ? L : -1;
}
Another solution from the book - two pointers
Let’s assume we have two indices pointing to the i
respectively. The sum of Ai and Aj could only fall into one of these three possibilities:
i. Ai + Aj > target. Increasing i isn’t going to help us, as it makes the sum even bigger. Therefore we should decrement j.
ii. Ai + Aj < target. Decreasing j isn’t going to help us, as it makes the sum even smaller. Therefore we should increment i.
iii. Ai + Aj == target. We have found the answer.
After suggestions:
public int[] twoSum3(int[] nums, int target) {
int[] ret = {-1, -1};
int i = 0, j = nums.length-1; //the two pointers
while(i < j){
if(nums[i]+nums[j] < target) i++;
else if(nums[i]+nums[j] > target) j--;
else{
ret[0] = i+1;
ret[1] = j+1;
System.out.println("index1="+ret[0]+", index2="+ret[1]);
return ret;
}
}
throw new IllegalArgumentException("No valid two numbers match.");
}