首页 > 其他分享 >leetCode:三数之和

leetCode:三数之和

时间:2024-11-10 21:20:49浏览次数:1  
标签:right temp nums 三数 lists add inList leetCode

题目:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

解题思路历程:

第一个想到的方法三个循环,第一个循环从数组的0索引(i)位置开始,第二个循环从数组的j(i+1)索引位置开始,第三个循环从数组的m(i+1+1)位置开始,然后输出nums[i]+nums[j]+nums[m] == 0的结果,但是这种做法会出现重复的三元组元素。如果需要去除这些重复元素,则需要再一次便历,这样算法的效率会大大降低,所以果断去除这种方式。所以在这种方式之后,我想如果把原始数组先排序,然后将排序之后的数组进行三重循环,每一层循环加一个if判断条件,如果当前位置元素与上一个位置元素的值相等,第一层循环的时候需要i>.0,第二重循环需要j-i>1,第三重循环需要m-j>1,这样输出的元素数组就不会再重复,此时算法的时间复杂度是O(N^3),但是如果使用双指针,这个算法会不会可以优化?

O(N^3)代码:
Arrays.sort(nums);
    System.out.println(Arrays.toString(nums));
    if (nums.length < 3) {
        return null;
    }
    int sum = 0;
    List<List<Integer>> lists = new ArrayList<>();
    List<Integer> inList = new ArrayList<>();
    if (nums.length == 3) {
        sum = nums[0] + nums[1] + nums[2];
        if (sum == 0) {
            inList.add(nums[0]);
            inList.add(nums[1]);
            inList.add(nums[2]);
            lists.add(inList);
        }
        return lists;
    }
    for (int i = 0; i < nums.length - 2; i++) {
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue;
        }
        for (int right = i + 1; right < nums.length - 1; right++) {
            if(nums[right] == nums[right - 1] && right - i > 1){
                continue;
            }
            int temp = right + 1;
            while(temp <= nums.length-1){
                if(nums[temp] == nums[temp - 1] && temp - right > 1){
                    ++temp;
                    continue;
                }
                inList = new ArrayList<>() ;
                if (nums[i] + nums[right] + nums[temp] == 0) {
                    inList.add(nums[i]);
                    inList.add(nums[right]);
                    inList.add(nums[temp]);
                    lists.add(inList);
                }
                temp++;
            }
        }
    }
    return lists;
}
第二种方法:维持前两个循环不变,在第二个循环上添加一个指针,并且得到目标值是-nums[i],这个指针从nums[]的末端开始前移,如果移动到跟第二个循环变量j相等,则直接跳出循环,指针前移的条件是m>j,nums[j] + nums[m] >
-nums[i],最后将nums[j] + nums[m] == -nums[i]的索引存入新的集合中,然后将该集合添加至要返回的集合中并返回,此时算法的时间复杂度是O(N^2)
O(N^2)代码:
public static List<List<Integer>> secondThreeSum(int[] nums) {
    nums = Arrays.stream(nums).sorted().toArray();
    Arrays.sort(nums);
    System.out.println(Arrays.toString(nums));
    if (nums.length < 3) {
        return null;
    }
    int sum = 0;
    List<List<Integer>> lists = new ArrayList<>();
    List<Integer> inList = new ArrayList<>();
    if (nums.length == 3) {
        sum = nums[0] + nums[1] + nums[2];
        if (sum == 0) {
            inList.add(nums[0]);
            inList.add(nums[1]);
            inList.add(nums[2]);
            lists.add(inList);
        }
        return lists;
    }
 


    for (int i = 0; i < nums.length - 2; i++) {
        if (i > 0 && nums[i] == nums[i - 1]) {
            continue;
        }
        int target = -nums[i];
        int temp = nums.length - 1;
        for (int right = i + 1; right < nums.length - 1; right++) {

            if(nums[right] == nums[right - 1] && right - i > 1){
                continue;
            }


            while((nums[right] + nums[temp]) > target && temp > right) {
                --temp;
            }
            if(temp == right){
                break;
            }
            inList = new ArrayList<>() ;
            if (nums[right] + nums[temp] == target) {
                inList.add(nums[i]);
                inList.add(nums[right]);
                inList.add(nums[temp]);
                lists.add(inList);
            }
        }
    }
    return lists;
}
 

标签:right,temp,nums,三数,lists,add,inList,leetCode
From: https://www.cnblogs.com/zwd04-03/p/18538505

相关文章

  • 一道题把我气笑了:) 力扣.53 最大子数组和 leetcode maximum-subarray
    数组系列力扣数据结构之数组-00-概览力扣.53最大子数组和maximum-subarray力扣.128最长连续系列longest-consecutive-sequence力扣.1两数之和N种解法two-sum力扣.167两数之和IItwo-sum-ii力扣.170两数之和IIItwo-sum-iii力扣.653两数之和IVtwo-sum-IV力......
  • [LeetCode] 3090. Maximum Length Substring With Two Occurrences
    Givenastrings,returnthemaximumlengthofasubstringsuchthatitcontainsatmosttwooccurrencesofeachcharacter.Example1:Input:s="bcbbbcba"Output:4Explanation:Thefollowingsubstringhasalengthof4andcontainsatmosttw......
  • LeetCode【0002】两数相加
    本文目录1中文题目2求解思路2.1基础解法:递归解法2.2最优解法:迭代法3题目总结1中文题目给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请将两个数相加,并以相同形式返回一个表示和的链表。说明:......
  • 闯关leetcode——3285. Find Indices of Stable Mountains
    大纲题目地址内容解题代码地址题目地址https://leetcode.com/problems/find-indices-of-stable-mountains/description/内容Therearenmountainsinarow,andeachmountainhasaheight.Youaregivenanintegerarrayheightwhereheight[i]represen......
  • [LeetCode] 1343. Number of Sub-arrays of Size K and Average Greater than or Equa
    Givenanarrayofintegersarrandtwointegerskandthreshold,returnthenumberofsub-arraysofsizekandaveragegreaterthanorequaltothreshold.Example1:Input:arr=[2,2,2,2,5,5,5,8],k=3,threshold=4Output:3Explanation:Sub-arrays[2......
  • [LeetCode] 2841. Maximum Sum of Almost Unique Subarray
    Youaregivenanintegerarraynumsandtwopositiveintegersmandk.Returnthemaximumsumoutofallalmostuniquesubarraysoflengthkofnums.Ifnosuchsubarrayexists,return0.Asubarrayofnumsisalmostuniqueifitcontainsatleastmdisti......
  • 力扣(LeetCode)106. 从中序与后序遍历序列构造二叉树
    一、目标  给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。二、代码分析总体代码:/***Definitionforabinarytreenode.*publicclassTreeNode{*int......
  • 104.力扣(leetcode)二叉树的最大深度(JAVA)
    一、目标给定一个二叉树 root ,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。二、代码分析总代码:/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeN......
  • 力扣(Leetcode)112. 路径总和(JAVA)
    一、目标 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。叶子节点 是指没有子节点的节点。二、代码解读......
  • 257. 力扣(LeetCode)二叉树的所有路径(JAVA)
    一、目标给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。叶子节点 是指没有子节点的节点。二、代码解读总代码:/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*......