LeetCode # Array # Easy # 167. Two Sum II - Input array is sorted

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.

题目:给定一个排序数组,和一个目标值。要求在数组中找出和为目标值的两个数,并给出索引。注意索引不是从0开始,而是从1开始。

注意:假设数组中一定会有一组数符合要求 ,每个元素只用一次。

思路:当目标值为0时,直接返回{1,2}。 按照题意,一定会有两个0元素,且排序在数组最前。

  然后用for循环,找到两个索引后跳出。

 1 class Solution {
 2     public int[] twoSum(int[] numbers, int target) {
 3          int[] index = {1,2};
 4          int t2 = 0;
 5         if(target == 0){//直接返回{1,2}
 6              return index;
 7          }
 8          for(int i = 0; i< numbers.length; i++){
 9              boolean k = false;
10             if(numbers[i] != 0){ //当前值不为0,才进入内层循环                
11                  index[0] =i+1; 
12                   t2 = target - numbers[i];
13                   for(int j = i+1; j<numbers.length; j++){
14                       if(numbers[j]==t2){
15                           index[1]= j+1;
16                           k=true; //用于控制外层循环跳出;
17                           break;
18                       }                  
19                   }
20                   if(k == true){ 
21                       break;
22                   }
23              }
24          }
25          return index; 
26     }
27 }

虽然这个方案是自己一步步改出来的, 很激动哇。但是发现时间上较差,只超过18%的submit。可以看出我的方案是0(n2)的。

参考最佳方案进行改进,Java solution - 0ms, beat 100% 。

该方法的思路是使用二分查找,我把两个元素的索引值小的称为小数,大的称为大数。

如果数组首尾元素之和大于目标值,则说明尾部的值较大,应该减小。所以,用二分法,查找一个合适的大数。

如果数组首尾元素之和小于目标值,则说明首部的值较小,应该增大。所以,查找一个合适的小数。

 1 class Solution {
 2     public int[] twoSum(int[] numbers, int target) {
 3        int l = 0, h = numbers.length - 1, sum;
 4         while ((sum = numbers[l] + numbers[h]) != target && h != l) {
 5             if (sum > target)
 6                 h = binarySearch(numbers, l + 1, h - 1, target - numbers[l]);//寻找一个合适的大数
 7             else if (sum < target)
 8                 l = binarySearch(numbers, l + 1, h - 1 , target - numbers[h]);//寻找一个合适的小数
 9         }                
10         return new int[]{l + 1, h + 1};
11     }
12 
13   private int binarySearch(int[] numbers, int low, int high, int target) {
14         while (low < high) {
15             int mid = (low + high) / 2;                        
16             if (target == numbers[mid]) {
17                 return mid;
18             } else if (target < numbers[mid]) {
19                 high = mid;
20             } else
21                 low = mid + 1;
22         }
23         return high;
24     }
25 }

可以看出,该方案是0(nlogn)的。二分法真的很重要。

猜你喜欢

转载自www.cnblogs.com/DongPingAn/p/8994306.html