15三数之和&&18四数之和

91 阅读1分钟

一开始错的想法与解答

Map<Integer,Integer> map = new HashMap<>();
        int temp = 0;
        for(int i = 0;i<nums.length;i++){
            for(int j = 0;j<nums.length;j++){
                temp = nums[i]+nums[j];
                if(map.containsKey(temp)){
                    continue;
                }
                else {
                    map.put(temp,1);
                }
            }
        }
        for(int i =0;i<nums.length;i++){
            if(map.containsKey(0-nums[i])){
                //一开始把这个想太简单了,认为利用hash表就能达到去重检索的了,
                //但这样子是无法返回具体三元组的值的,只能返回次数。
            }
        }
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        //运用三指针的想法去做。首先创建一个二元数组
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);   //排序是关键,这样下面的if判断才能做出成效
        for(int i = 0;i<nums.length;i++){  //这里一开始忘记i也要进行移动,不能一直放在0索引处
            if(nums[i]>0){
                return res;
            }
            //i没有去重判断,所以测试用例又有一个错误的了
            if(i>0&&nums[i]==nums[i-1]){
                continue;   //这个continue的意思是跳出这一次,i+1,去往下一次循环但是不跳循环
            }
        int left = i+1;
        int right = nums.length-1;
        while(right>left){
            if(nums[i]+nums[left]+nums[right]>0){
                right--;
            }
            else if(nums[i]+nums[left]+nums[right]<0){
                left++;
            }
            else {
                res.add(Arrays.asList(nums[i],nums[left],nums[right]));
                while(right>left&&nums[left]==nums[left+1]){   //要一直判断边界,要不然会出去
                    left++;
                }
                while(right>left&&(nums[right]==nums[right-1])){
                    right--;
                }
                left++;
                right--;   //假如没有相同的,left和right也要进行移动,判断完同样的就忘记判断这个了
            }
        }
        }
        return res;
    }
}

做18四数之和,做到崩溃,首先是超出时间限制,发现是原本while的地方变成了if,改过来了。然后又是超出内存限制。。。现在附上错误代码,错误代码下面则是正确ac代码

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        int sum = 0;
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);        
        if(nums==null) {
            return res;
        }

        for(int i = 0;i<nums.length-1;i++){
            //这里应该进行一个剪枝操作就可以减少时间运行
            if(nums[i]>0&&nums[i]>target){
                return res;
            }
            if(i>0&&nums[i]==nums[i-1]){   //这里应该是if,而不是又套一层循环
                    continue;
                }
            for(int j =nums.length-1;j>0;j--) {
                if(j<(nums.length-1)&&nums[j]==nums[j+1]){
                    continue;
                }
                int left = i+1;
                int right = j-1;
                while(left<right) {
                    int temp = nums[i]+nums[j]+nums[left]+nums[j];
                    if(temp<target){
                        left++;
                    }
                    else if(temp>target){
                        right--;
                    }
                    else {
                        res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while(left<right&&nums[left]==nums[left-1]){   //这里的循环又忘
                        //了,没有理解深刻
                            left++;
                        }
                        while(left<right&&nums[right]==nums[right+1]){
                            right--;
                        }
                        }
                    }
                }
            }return res;
        }
    }

正确解答:

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);        
        if(nums==null) {
            return res;
        }

        for(int i = 0;i<nums.length;i++){
            //这里应该进行一个剪枝操作就可以减少时间运行
            if(nums[i]>0&&nums[i]>target){
                return res;
            }
            if(i>0&&nums[i]==nums[i-1]){   //这里应该是if,而不是又套一层循环
                    continue;
                }
            for(int j =i+1;j<nums.length;j++) {
                if(j>(i+1)&&nums[j]==nums[j-1]){
                    continue;
                }
                int left = j+1;
                int right = nums.length-1;
                while(left<right) {
                    int temp = nums[i]+nums[j]+nums[left]+nums[right];   //rnm,原本right写成了j...
                    if(temp<target){
                        left++;
                    }
                    else if(temp>target){
                        right--;
                    }
                    else {
                        res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while(left<right&&nums[left]==nums[left+1]){   //这里的循环又忘了,没有理解深刻
                            left++;
                        }
                        while(left<right&&nums[right]==nums[right-1]){
                            right--;
                        }
                        left++;  //又tm忘记了这里要++和--了
                        right--;
                        }
                    }
                }
            }return res;
        }
    }