给定一个升序排列的整数数组 numbers ,从数组中找出两个数满足相加之和等于目标数 target 。
    假设每个输入只对应唯一的答案,而且不可以重复使用相同的元素。
    返回两数的下标值,以数组形式返回
    解法一:暴力解法

    1. public int[] twoSum(int[] nums, int target) {
    2. int n = nums.length;
    3. for (int i = 0; i < n; ++i) {
    4. for (int j = i + 1; j < n; ++j) {
    5. if ((nums[i] + nums[j]) == target) {
    6. return new int[] { i, j };
    7. }
    8. }
    9. }
    10. return new int[0];
    11. }

    时间复杂度:O(N的平方)
    空间复杂度:O(1)

    解法二:哈希表:将数组的值作为key存入map,target - num作为key

    1. public int[] twoSum(int[] nums, int target) {
    2. Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    3. for (int i = 0; i < nums.length; ++i) {
    4. if (map.containsKey(target - nums[i])) {
    5. return new int[] { map.get(target - nums[i]), i };
    6. }
    7. map.put(nums[i], i);
    8. }
    9. return new int[0];
    10. }

    时间复杂度:O(N)
    空间复杂度:O(N)

    解法三:二分查找
    先固定一个值(从下标0开始),再用二分查找查另外一个值,找不到则固定值向右移动,继续二分查找

    1. public int[] twoSearch(int[] numbers, int target) {
    2. for (int i = 0; i < numbers.length; ++i) {
    3. int low = i;
    4. int high = numbers.length - 1;
    5. while (low <= high) {
    6. int mid = ((high - low) / 2) + low;
    7. if (numbers[mid] == (target - numbers[i])) {
    8. return new int[] { i, mid };
    9. } else if (numbers[mid] > (target - numbers[i])) {
    10. high = mid - 1;
    11. } else {
    12. low = mid + 1;
    13. }
    14. }
    15. }
    16. }

    时间复杂度:O(N * logN)
    空间复杂度:O(1)

    解法四:双指针
    左指针指向数组head,右指针指向数组tail,head+tail > target 则tail 左移,否则head右移

    1. public int[] twoPoint(int[] numbers, int target) {
    2. int low = 0;
    3. int high = numbers.length - 1;
    4. while (low < high) {
    5. int sum = numbers[low] + numbers[high];
    6. if (sum == target) {
    7. return new int[] { low + 1, high + 1 };
    8. } else if (sum < target) {
    9. ++low;
    10. } else {
    11. --high;
    12. }
    13. }
    14. return new int[] { -1, -1 };
    15. }

    时间复杂度:O(N)
    空间复杂度:O(1)