首页 > 其他分享 >两数之和、三数之和、四数之和(双指针)

两数之和、三数之和、四数之和(双指针)

时间:2023-02-21 18:45:30浏览次数:47  
标签:四数 target nums int 三数 long continue 两数 指针

两数之和:1. 两数之和 - 力扣(LeetCode)

思路:单次循环,利用哈希表 :key存储值,val存储索引;

时间复杂度、空间复杂度 均为 : O(N)

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int>hashtable;
        for(int i = 0;i < nums.size();++i){
            auto it = hashtable.find(target-nums[i]);
            if(it != hashtable.end()){
                return {it->second,i};
            }
            hashtable[nums[i]] = i;
        }
        return {};
    }
};

 

三数之和:15. 三数之和 - 力扣(LeetCode)

思路:排序+双指针, 数组进行排序,方便处理

   第一层循环 扫描数组,第二层循环,利用双指针,减少时间复杂度; 

   第一层和第二层的去重操作,利用continue 跳出此次循环,接着下一次循环

时间复杂度:O(N2);空间复杂度:O(log N) 

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(),nums.end());
        vector<vector<int>>res;
        for(int i = 0; i < n; ++i){
            if(i > 0 && nums[i] == nums[i-1]) continue;
            int k = n -1;
            int twoSum = -nums[i];
            for(int j = i +1;j < n;++j){
                if(j>i+1 && nums[j] == nums[j-1]) continue;
                while(j < k && nums[j]+nums[k] > twoSum) --k;
                if(j == k) break;//随着j的增加,k要减小
                if(nums[j] + nums[k] == twoSum) res.push_back({nums[i],nums[j],nums[k]});
            }
        }
        return res;
    }
};

 

四数之和:18. 四数之和 - 力扣(LeetCode)

思路:排序+双指针+剪枝, 数组进行排序,方便处理

  去重:如若此数等于上次枚举的数字,直接进入下一次循环---采用continue;

  剪枝:nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target;四数之和大于target,因排序数组,所以此后的数字和只能是越来越大,因此退出第一重循环---采用break;

     此处防止溢出,采用long long型变量;

     nums[i] + nums[n-3] + nums[n-2] + nums[n-1] < target;说明此数与最大的三个之和小于target,那么跳出本次循环,开启下一次循环---词用continue;

   第一层循环,去重+剪枝,固定第一个数字

   第二层循环,去重+剪枝,固定第二个数字

   第三层循环,双指针+去重,确定剩下的两个数字

         左指针m、右指针k,判断其与剩下的两个数字和的大小,大于则 右指针左移,小于 则 左指针右移,相等就压入数组中,并执行右指针左移,左指针右移;同时判断下一次的值是否与此次相同,即去重操作;

时间复杂度:O(N3) ;空间复杂度:O(log N)

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size();
        if(n < 4) return {};
        sort(nums.begin(),nums.end());
        vector<vector<int>>res;
        for(int i = 0;i < n-3;++i){
            if(i > 0 && nums[i] == nums[i-1]) continue;
            if((long long)nums[i]+nums[i+1]+nums[i+2]+nums[i+3] > target) break;
            if((long long)nums[i]+nums[n-1]+nums[n-2]+nums[n-3] < target) continue;
            for(int j = i+1;j < n-2;++j){
                if(j > i+1 && nums[j] == nums[j-1]) continue;
                if((long long)nums[i]+nums[j]+nums[j+1]+nums[j+2] > target) break;
                if((long long)nums[i]+nums[j]+nums[n-1]+nums[n-2] < target) continue;
                int twoSum = target - (nums[i] + nums[j]);
                int m = j + 1,k = n-1;
                while(m < k){
                    if(nums[m]+nums[k] > twoSum) --k;
                    else if(nums[m]+nums[k] < twoSum) ++m;
                    else{
                        res.push_back({nums[i],nums[j],nums[m],nums[k]});
                        --k;++m;
                        while(m < k && nums[m] == nums[m-1]) ++m;
                        while(m < k && nums[k] == nums[k+1]) --k;
                    }               
                }
            }
        }
        return res;
    }
};

 

标签:四数,target,nums,int,三数,long,continue,两数,指针
From: https://www.cnblogs.com/xuan01/p/17141810.html

相关文章

  • leetcode 1. 两数之和 暴力穷举 排序 哈希表 时间比较
    暴力O(n*n)#include<iostream>#include<stdio.h>#include<vector>#include<algorithm>#include<map>#include<unordered_map>usingnamespacestd;//暴......
  • 代码随想录打卡第5天 |有效的字母异位词, 两个数组的交集, 快乐数,两数之和
    有效的字母异位词1,用一个长度为26的数组s[s.charAt(i)-'a']存大于0说明有多 小于0说明缺少两个数组的交集1,用两个set集合第一个set集合存t,第二个set用......
  • LeetCode题2两数相加
    2.两数相加分析题目比较简单,就是两个数相加求和。按照加法思想,同时遍历两个链表,从个位一直加到最高位即可。比如要计算352+99,步骤如下:最低位2+9得11,需进位,个位保留......
  • Leetcode题1两数之和 JavaScript语言
    1.两数之和方案一,暴力双循环读完题目,马上能想到的方案就是双循环,挨个排查,写出来也很快:vartwoSum=function(nums,target){constlen=nums.length;for......
  • A - k-rounding 【2022级专题四数论课后练习】
    A-k-rounding[原题链接]思路求\(n\)和\(10^k\)的最小公倍数最小公倍数和最大公因数的关系\(a\cdotb=最小公倍数\cdot最大公因数\)代码点击查看代码#incl......
  • 2. 两数相加
    给你两个 非空的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和......
  • #yyds干货盘点# LeetCode面试题:四数之和
    1.简述:给你一个由n个整数组成的数组 nums,和一个目标值target。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a],nums[b],nums[c],nums[d]] (若两个四元......
  • 【LeetCode】三数之和
    三数之和题目描述给你一个整数数组nums,判断是否存在三元组[nums[i],nums[j],nums[k]]满足i!=j、i!=k且j!=k,同时还满足nums[i]+nums[j]+nums[k]==......
  • 【LeetCode】15. 三数之和
    classSolution{public:vector<vector<int>>threeSum(vector<int>&nums){vector<vector<int>>result;sort(nums.begin(),nums.end());......
  • 【力扣题目】两数相加(链表)
    https://leetcode.cn/problems/add-two-numbers/1/**2*Definitionforsingly-linkedlist.3*publicclassListNode{4*intval;5*List......