算法-数列-两数之和

120 阅读2分钟

LeetCode原题:

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。 示例 1:

输入:numbers = [2,7,11,15], target = 9 输出:[1,2] 解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

针对排好序的数组有如下方法: 二分查找:

/**
* 使用二分查找定位 nums[mid] == target - nums[i]
* 二分查找,时间复杂度  O(nlogn),空间复杂度O(1)
* @param  nums:   整数数组 
* @param  target: 目标数 
* @return  以数组形式返回两数的下标值,未找到返回空数据 
*/
public static int[] twoSearch(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        int low = i, hight = nums.length - 1;
        while (low <= hight) {
            int mid = (hight - low) / 2 + low;
            if (nums[mid] == target - nums[i]) {
                return new int[]{i, mid};
            } else if (nums[mid] > target - nums[i]) {
                hight = mid - 1;
            } else {
                low = mid + 1;
            }
        }
    }
    return new int[]{0};
}

双指针:

/**
     * 双指针法,时间复杂度O(n),空间复杂度O(1),最优解,前提是有序数组
     * 头指针和尾指针之和等于于要查找的数时,返回头尾指针的坐标
     * 头指针和尾指针之和大于要查找的数时,high--
     * 头指针和尾指针之和小于于要查找的数时,low++
     * @param nums:   整数数组
     * @param target: 目标数
     * @return 以数组形式返回两数的下标值,未找到返回空数据
     */
public static int[] twoPoint(int[] nums, int target) {
    int low = 0, high = nums.length - 1;
    while (low < high) {
        if (nums[low] + nums[high] == target) {
            return new int[]{low, high};
        } else if (nums[low] + nums[high] > target) {
            high--;
        } else {
            low++;
        }
    }
    return new int[]{0};
}

hash:针对于没有排序的

public int[] twoSum(int[] nums, int target) {
    //存储(元素,下标)
    Map<Integer,Integer> map = new HashMap<Integer,Integer>();
    for(int i=0;i<nums.length;i++){
        //map存在target与当前数之差,返回map中下标和当前下标的数组
        if(map.containsKey(target-nums[i])){
            return new int[]{ map.get(target-nums[i]), i };
        }
        map.put(nums[i],i);
    }
    return new int[0];

}