1. Two Sum && 167. Two Sum II

来源:互联网 发布:fatezero的saber 知乎 编辑:程序博客网 时间:2024/05/13 22:19

1. Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9,return [0, 1].


思路:刚开写的是排序再用2 pointer的解法,TLE

修正问HashMap的解法,AC

/* * 在HashMap查找效率为O(1)时,该解法是O(n)的复杂度 */public class Solution {    public int[] twoSum(int[] nums, int target) {                Map<Integer, Integer> map = new HashMap<Integer, Integer>();        int[]rst = new int[2];                for(int i=0; i<nums.length; i++) {            if(map.containsKey(nums[i])) {                rst[0] = map.get(nums[i]);                rst[1] = i;                return rst;            }            map.put(target-nums[i], i);           }        return rst;    }}


/* * 2 pointer 解法 * 复杂度O(nlogN), TLE */public class Solution {    public int[] twoSum(int[] nums, int target) {    Arrays.sort(nums);    int p = 0, q = nums.length-1;    int[] rst = new int[2];        while(p < q) {    int sum = nums[p] + nums[q];    if(sum == target) {    rst[0] = nums[p];    rst[1] = nums[q];    } else if(sum > target) {    q --;    } else {    p ++;    }    }    return rst;            }}




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. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution and you may not use the same element twice.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2


思路:用2 pointer和HashMap都可以,复杂度一样的

public class Solution {    public int[] twoSum(int[] nums, int target) {                Map<Integer, Integer> map = new HashMap<Integer, Integer>();        int[]rst = new int[2];        int cnt = 0;                for(int i=0; i<nums.length; i++) {            if(map.containsKey(nums[i])) {                rst[0] = map.get(nums[i]) + 1;                rst[1] = i + 1;                return rst;            }            map.put(target-nums[i], i);           }        return rst;    }}




15. 3Sum

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],A solution set is:[  [-1, 0, 1],  [-1, -1, 2]]


思路:之前有个2sum的问题,用2个pointer解决,3sum就是外面多了层循环

 (可以不用排序用HashMap,但是并不能降低复杂度)

import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class Solution {    public List<List<Integer>> threeSum(int[] nums) {            List<List<Integer>> rst = new ArrayList<List<Integer>>();    Arrays.sort(nums);        int p1, p2, left;    for(int i=0; i<nums.length-2; i++) {    while(i > 0 && i < nums.length - 2 && nums[i] == nums[i-1])i++;    left = 0 - nums[i];    p1 = i + 1;    p2 = nums.length - 1;    while(p1 < p2) {    if(nums[p1] + nums[p2] == left) {    List<Integer> t = new ArrayList<Integer>();    t.add(nums[p1]);t.add(nums[p2]);t.add(nums[i]);    rst.add(t);    int tp1 = nums[p1], tp2 = nums[p2];    while(p1 < p2 && nums[p1] == tp1)p1++;    while(p1 < p2 && nums[p2] == tp2)p2 --;    } else if(nums[p1] + nums[p2] > left) {    p2 --;    } else {    p1 ++;    }    }    }        return rst;    }}




16. 3Sum Closest 

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).


思路:跟15. 3Sum http://blog.csdn.net/zjucor/article/details/53159578类似,无非是在一个数组中找两个数加起来等于某个数变为了:在一个数组中找两个数加起来最接近某个数

这个时候用HashMap无能为力,只能sort + 2 pointer

复杂度O(N^2)

import java.util.Arrays;public class Solution {    public int threeSumClosest(int[] nums, int target) {        int rst = 0, min = Integer.MAX_VALUE;                Arrays.sort(nums);                int p1, p2, left;    for(int i=0; i<nums.length-2; i++) {    while(i > 0 && i < nums.length - 2 && nums[i] == nums[i-1])i++;    p1 = i + 1;    p2 = nums.length - 1;    while(p1 < p2) {    int cur = nums[p1] + nums[p2] + nums[i];    if(cur > target) {    if(cur -target < min) {    min = cur -target;    rst = cur;    }    p2 --;    } else if(cur < target) {    if(target - cur < min) {    min = target - cur;    rst = cur;    }    p1 ++;    } else {    return target;    }    }    }        //System.out.println("min diff : " + min);    return rst;    }}



18. 4Sum

Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.A solution set is:[  [-1,  0, 0, 1],  [-2, -1, 1, 2],  [-2,  0, 0, 2]]

思路:套路了,两层循环+two pointer

复杂度:O(N^3)

import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class Solution {    public List<List<Integer>> fourSum(int[] nums, int target) {    List<List<Integer>> rst = new ArrayList<List<Integer>>();    Arrays.sort(nums);        int p1, p2, left;    for(int i=0; i<nums.length - 3; i++) {    while(i != 0 && i < nums.length - 3 && nums[i] == nums[i-1])i++;    for(int j=i+1; j<nums.length - 2; j++) {    while(j != i+1 && j < nums.length - 2 && nums[j] == nums[j-1])j++;        left = target - nums[i] - nums[j];    p1 = j + 1;        p2 = nums.length - 1;        while(p1 < p2) {        if(nums[p1] + nums[p2] == left) {        List<Integer> t = new ArrayList<Integer>();        t.add(nums[p1]);t.add(nums[p2]);t.add(nums[i]);t.add(nums[j]);        rst.add(t);        int tp1 = nums[p1], tp2 = nums[p2];        while(p1 < p2 && nums[p1] == tp1)p1++;        while(p1 < p2 && nums[p2] == tp2)p2 --;        } else if(nums[p1] + nums[p2] > left) {        p2 --;        } else {        p1 ++;        }        }    }    }            return rst;    }}


1 0