ダブルポインター+少しの最適化:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int left=0;
int right=numbers.length-1;
while(left<=right){
int mediate=left+(right-left)/2;
if(numbers[left]+numbers[right]==target) return new int[] {
left+1,right+1};
else if(numbers[left]+numbers[right]<target){
if(numbers[mediate]+numbers[right]<target) left=mediate+1;
else if(numbers[mediate]+numbers[right]>target) left=left+1;
else return new int[] {
mediate+1,right+1};
}
else if(numbers[left]+numbers[right]>target){
if(numbers[mediate]+numbers[left]>target) right=mediate-1;
else if(numbers[mediate]+numbers[left]<target) right=right-1;
else return new int[] {
left+1,mediate+1};
}
}
return null;
}
}
非常に巧妙な書き方を見たので、二分法を使用して正しい範囲を決定し、次にダブルポインターを使用して最終結果を決定することができます。
class Solution {
public int[] twoSum(int[] numbers, int target) {
if(numbers==null) return null;
int tail=Dichotomy(numbers,target-numbers[0]);
int head=0;
while(head<tail){
int sum=numbers[head]+numbers[tail];
if(sum==target) return new int[]{
head+1,tail+1};
else if(sum<target) head++;
else tail--;
}
return null;
}
private int Dichotomy(int[] numbers,int target){
//找到了最接近目标值的下标
int left=0;
int right=numbers.length-1;
while(left<=right){
int mediate=left+(right-left)/2;
if(numbers[mediate]==target) return mediate;
else if(numbers[mediate]>target) right=mediate-1;
else left=mediate+1;
}
return left-1;//即返回的num[left-1]<target
}
}
もしnums[i]>target-nums[0]
そうなら、nums [i]と右側は間違いなくあなたが望むものではありません。
必要nums[i]<=target-nums[0]
です。そして、二分法はこの問題を解決します。
+の優先度が>>よりも高いため、8+(10)>>1
結果は13ではなく9になることも理解しています。