当前位置: 首页 > article >正文

1_相向双指针_leetcode_15_2

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

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

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1][-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0
提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105

方法一 穷举搜索 (时间复杂度过高,不展示)

  • 时间复杂度:O( n 3 n^3 n3)
  • 空间复杂度: O ( 1 ) O(1) O(1)

方法二 相向双指针

借助之前1_相向双指针_leetcode_167_1 相向双指针可以将 O ( n 2 ) O(n^2) O(n2)的问题下降值 O ( n ) O(n) O(n),前提是数组有序,所以这题可以先使用快速排是让数组先变得有序,之后使用相向双指针解决。

// C
int cmp(const void *a,const void *b){
    return *(int*)a - *(int*)b;
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
    *returnSize = 0;
    int **ret = (int **)malloc(sizeof(int*) * numsSize * numsSize);
    *returnColumnSizes = (int *)malloc(sizeof(int)* numsSize * numsSize);
    qsort(nums,numsSize,sizeof(int),cmp);

    for(int i = 0;i<numsSize-2;i++){
        if(i != 0 && nums[i-1] == nums[i]) continue; 
        if(nums[i] + nums[i+1] + nums[i+2] > 0) break;
        if(nums[numsSize-1]+nums[numsSize-2]+nums[i]<0) continue;
        int l = i+1;
        int r = numsSize-1;
        while(l<r){
            int sum = nums[l] + nums[r];
            if(sum > -nums[i]){
                r--;
            }else if(sum < -nums[i]){
                l++;
            }else{
                ret[*returnSize] = (int*)malloc(sizeof(int)*3);
                ret[*returnSize][0] = nums[i];
                ret[*returnSize][1] = nums[l];
                ret[*returnSize][2] = nums[r];
                (*returnColumnSizes)[*returnSize] = 3;
                r--;l++;(*returnSize)++;
                while(l<r && nums[l]==nums[l-1]) l++;
                while(l<r && nums[r]==nums[r+1]) r--;
                
            }
        }

    }
    return ret;
}
// C++
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int sum = 0;
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret;
        for(int i = 0;i<nums.size()-2;i++){
            if(i > 0 && nums[i] == nums[i-1]) continue;
            if(nums[i] + nums[i + 1] + nums[i+2] > 0) break;
            if(nums[i] + nums[nums.size()-1] + nums[nums.size()-2] < 0 ) continue;
            int r = nums.size()-1;
            int l = i + 1;
            while(l < r){
                sum = nums[i] + nums[l] + nums[r];
                if(sum < 0) l++;
                else if (sum > 0) r--;
                else{
                    ret.push_back({nums[i],nums[l],nums[r]});
                    for(l++; l < nums.size() && nums[l]==nums[l-1];l++);
                    for(r--;r > -1 && nums[r]==nums[r+1];r--);
                }
            }
        }
        return ret;
    }
};
#python
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        result = []
        
        for i in range(len(nums)-2):
            if nums[i] + nums[i + 1] + nums[i + 2] > 0: break
            if i != 0 and nums[i] == nums[i - 1]: continue
            if nums[i] + nums[len(nums)-1] + nums[len(nums)-2] < 0: continue
            left, right = i+1, len(nums)-1
            target = -nums[i]
            while left < right:
                twoSum = nums[left] + nums[right]
                if  twoSum > target:
                    right -= 1
                elif twoSum < target:
                    left += 1
                else:
                    result.append([nums[i],nums[left],nums[right]])
                    right -= 1
                    left += 1
                    while left < right and nums[left] == nums[left -1]: left += 1
                    while left < right and nums[right] == nums[right+1]: right -= 1
                    
        return result               
  • 时间复杂度:O( n 2 n^2 n2)
  • 空间复杂度: O ( l o g n ) O(logn) O(logn)

http://www.kler.cn/a/521493.html

相关文章:

  • 计算机网络一点事(22)
  • 深入理解Flexbox:弹性盒子布局详解
  • 玩转大语言模型——使用langchain和Ollama本地部署大语言模型
  • P1044 [NOIP2003 普及组] 栈 C语言
  • 134.力扣刷题--加油站--滑动窗口
  • docker中运行的MySQL怎么修改密码
  • inception_v3
  • 61.异步编程1 C#例子 WPF例子
  • 架构基础常识
  • Go 程序开发的注意事项
  • 安装 Prometheus、Grafana 和 Alertmanager
  • c++的容器和适配器究竟有什么差别?
  • 统计安卓手机一段时间内进程中每个线程的平均CPU使用率
  • mysql 学习6 DQL语句,对数据库中的表进行 查询 操作
  • http跳转https
  • Prism--对话服务
  • 如何使用DDD 的思想规划对应的模块
  • arcgis短整型变为长整型的处理方式
  • window保存好看的桌面壁纸
  • 一文讲解JVM中的G1垃圾收集器
  • 什么是vue.js组件开发,我们需要做哪些准备工作?
  • 洛谷题目: P2188 小Z的 k 紧凑数 (本题较难,省选-难度)题解
  • 深度学习:基于MindNLP的RAG应用开发
  • Python Typing: 实战应用指南
  • 安装Office自定义项,安装期间出错
  • 力扣算法题——11.盛最多水的容器