每日一题2

题目:15. 三数之和

初始版:

遇到了问题,在进行了T.add(S)后,最终的T却是空值。


import java.util.*;

class S2 {
    public List<List<Integer>> threeSum(int[] nums) {
        int i=0,j=1,k=2;
        List<List<Integer>> T = new ArrayList<List<Integer>>(hs);
        List<Integer> S=new ArrayList<Integer>();
        for(i=0;i<nums.length-2;i++){
            for(j=i+1;j<nums.length-1;j++){
                for(k=j+1;k<nums.length;k++){  
                    if(nums[i]+nums[j]+nums[k]==0){
                        S.add(nums[i]);
                        S.add(nums[j]);
                        S.add(nums[k]);  
                        T.add(S);                     
                        System.out.println(T);
                        System.out.print(i+" "+j+" "+k+"\n");
                        S.clear();
                    }

                }
            }
        } 
        System.out.println(T);
        System.out.println(hs);
        return T;
    }
}

解决:

import java.util.*;

class S2 {
    public List<List<Integer>> threeSum(int[] nums) {
        int i=0,j=1,k=2;
        List<List<Integer>> T = new ArrayList<List<Integer>>();
        for(i=0;i<nums.length-2;i++){
            for(j=i+1;j<nums.length-1;j++){
                for(k=j+1;k<nums.length;k++){
                    List<Integer> S=new ArrayList<Integer>();    //每次重新声明,再进行T.add(S)即可
                    if(nums[i]+nums[j]+nums[k]==0){
                        S.add(nums[i]);
                        S.add(nums[j]);
                        S.add(nums[k]);
                        Collections.sort(S);
                        T.add(S);  //每次add不同的引用
                     // System.out.println(T);
                        System.out.print(i+" "+j+" "+k+"\n");
                     // S.clear();   //不需要进行清除了
                    }

                }
            }
        }
        return T;
    }
}

但是以上遇到了复杂度过大以及重复出现的问题,后面采用排序去除重复,同时采用双指针降低复杂度。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        // 枚举 a
        for (int first = 0; first < n; ++first) {
            // 需要和上一次枚举的数不相同
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            // c 对应的指针初始指向数组的最右端
            int third = n - 1;
            int target = -nums[first];
            // 枚举 b
            for (int second = first + 1; second < n; ++second) {
                // 需要和上一次枚举的数不相同
                if (second > first + 1 && nums[second] == nums[second - 1]) {
                    continue;
                }
                // 需要保证 b 的指针在 c 的指针的左侧
                while (second < third && nums[second] + nums[third] > target) {
                    --third;
                }
                // 如果指针重合,随着 b 后续的增加
                // 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
                if (second == third) {
                    break;
                }
                if (nums[second] + nums[third] == target) {
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    ans.add(list);
                }
            }
        }
        return ans;
    }
}

知识点:

hashset->List:

HashSet<List<Integer>> hs = new HashSet<List<Integer>>();
List<List<Integer>> T = new ArrayList<List<Integer>>(hs);

List 排序:

Collections.sort(S);  //S->List

数组排序:

Arrays.sort(nums); // int[] nums;
posted @ 2023-02-19 15:51  ZLey  阅读(11)  评论(0编辑  收藏  举报