1. Two Sum&15. 3Sum

Question

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.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
思路一

暴力解决用两个for循环,时间复杂度为O(n^2);

思路二

用hash表存入每一个元素,遍历数组中的元素,然后查找目标和该元素的差。

代码
public class Solution {
    public int[] twoSum(int[] nums, int target) {
        //要考虑负数的情况
        int[] result = new int[2]; 
        if(nums.length < 2)
            return result;
        Map<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i = 0;i < nums.length;i++){
            if(map.containsKey(target - nums[i])){
                int res = map.get(target - nums[i]);
                if(i != res){
                    //由于查找出来的结果总是在前面存的,所以res永远小于i
                    result[1] = i;
                    result[0] = res;
                    return result;
                }
            }
            map.put(nums[i],i);
        }
        return result;
    }
}
结果及分析

【You are here!
Your runtime beats 40.16% of javasubmissions.】时间复杂度为O(n),空间复杂度也一样。

15. 3Sum Question

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]
]
思路

在计算之前先排序,然后遍历数组作为第一个数,求出剩余两个数的和,然后设置连个指针分别从数组的两边向中间靠拢,如果两个指针的和小于所要求的和,则左侧指针右移,反之右侧指针左移,这里需要注意的是不能出现重复的。所以遍历的时候如果下一个遍历的值和本次遍历的值相同则跳过本次遍历。

代码
    public List<List<Integer>> threeSum(int[] nums) {
        //首先进行排序,排序的目的是控制指针的移动,如果目前的和小于目标则左移,否则右移
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(nums.length < 3)
            return result;
        Arrays.sort(nums);
        for(int first = 0;first < nums.length - 2;first++){
            if(first > 0 && nums[first] == nums[first - 1])//避免重复
                continue;
            int target = 0 - nums[first];
            int sec = first + 1,third = nums.length - 1;
            while(sec < third){
                if(nums[sec] + nums[third] == target){
                    List<Integer> cur = new ArrayList<Integer>();
                    cur.add(nums[first]);
                    cur.add(nums[sec]);
                    cur.add(nums[third]);
                    result.add(cur);
                    while(sec < third && nums[sec] == nums[sec + 1]) sec++;
                    while(sec < third && nums[third] == nums[third - 1]) third--;
                    sec++;
                    third--;
                }
                else if(nums[sec] + nums[third] < target)
                    sec++;
                else
                    third--;
            }
        }
        return result;
    }
结果及分析

【You are here!
Your runtime beats 60.52% of javasubmissions.】时间复杂度为O(n^2);还是比较优的解法。

18. 4Sum Question

Given an array S of n integers, are there elements a, b, c, 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]
]
思路借鉴了3Sum的解法
代码
public class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(nums.length < 4)
            return result;
        Arrays.sort(nums);
        for(int pre = 0;pre < nums.length - 3;pre++){
            if(pre > 0 && nums[pre] == nums[pre - 1])//避免重复
                continue;
            for(int first = pre + 1;first < nums.length - 2;first++){
                if(first > pre + 1 && nums[first] == nums[first - 1])//避免重复
                    continue;
                int newtarget = target - nums[pre] - nums[first];
                int sec = first + 1,third = nums.length - 1;
                while(sec < third){
                    if(nums[sec] + nums[third] == newtarget){
                        List<Integer> cur = new ArrayList<Integer>();
                        cur.add(nums[pre]);
                        cur.add(nums[first]);
                        cur.add(nums[sec]);
                        cur.add(nums[third]);
                        result.add(cur);
                        while(sec < third && nums[sec] == nums[sec + 1]) sec++;
                        while(sec < third && nums[third] == nums[third - 1]) third--;
                        sec++;
                        third--;
                    }
                    else if(nums[sec] + nums[third] < newtarget)
                        sec++;
                    else
                        third--;
                }
            } 
        }

        return result;
    }
}
结果及分析

【You are here!
Your runtime beats 60.66% of javasubmissions.】时间复杂度为O(n^3).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值