首页 > 其他分享 >力扣-15-三数之和

力扣-15-三数之和

时间:2022-08-17 23:22:42浏览次数:85  
标签:15 nums 三数 元素 力扣 secondIndex 数组 firstNum thirdIndex

直达链接

前两天刚做了梦开始的地方两数之和
常规思路是二层遍历,对于每个数都去遍历数组找有没有刚好能凑成指定数字的
进阶思路是使用hashmap,一次遍历,对于每个元素去看hahsmap里有没有能凑成一对的,有就直接返回(因为题设答案唯一),没有就插到hashmap里面去(键为值,值为索引位置)

题目要求不重复,那么其实也可以说i<j<k,即定义返回数组的下标是递增的
这让我想到了之前拿回溯做题,去重也这么干过

感觉这里确实可以这么干,写一个回溯函数,定义一个int参数值为上一个选中元素的下标,当前元素下标大于才能被选中,然后和满足题目要求就放入结果数组
但其实这么找出来的原始序列是有重复的……有时间回过头去看一下是怎么写的

标签是:“数组”“双指针”“排序”…没有回溯

双指针应该才是正解,我是直接写了个三重循环出来之前,但是好像不对

提示1说可以固定一个元素,然后剩下的就可以用两数之和去解决,但是感觉不太好

我看题解里说要数组元素a<=b<=c,这样你还要排个序,然后又说元素大小不能一样…何必呢
用数组下标不香吗,好吧,也要考虑元素大小不能一样,还真就不香了

看完亮点思路应该是把三重循环变成了一重循环+双指针,但其实能这么做首先是因为题目“求和”的设定,另外,前面用了sort()排过一遍序的原因
思路理解没问题了,但是感觉跟那边的【三元组】还是有比较大不同的,那边强制要求了下标

class Solution {
public:
	vector<vector<int>> threeSum(vector<int>& nums) {
		if (nums.size() < 3) return {};
		vector<vector<int>> ret;
		sort(nums.begin(), nums.end());

		for (int firstNum = 0; firstNum < nums.size() - 2; ++firstNum) {
			// 如果排序后的第一个元素就大于0,后面不用看了,但是之前已经放入结果数组中的要算
			if (nums[firstNum] > 0) return ret;
			if (firstNum > 0 && nums[firstNum] == nums[firstNum - 1]) continue;

			int secondIndex = firstNum + 1, thirdIndex = nums.size() - 1;

			while (secondIndex < thirdIndex) {
				// 前两个判断语句是为了不等,但是不需要同时移动
				if (nums[secondIndex] + nums[thirdIndex] > -nums[firstNum]) thirdIndex--;
				else if (nums[secondIndex] + nums[thirdIndex] < -nums[firstNum]) secondIndex++;
				else {
					ret.push_back({ nums[firstNum],nums[secondIndex],nums[thirdIndex] });
					secondIndex++;
					thirdIndex--;

					// 例如:[-4,1,1,1,2,3,3,3], i=0, left=1, right=5
					// 上面各自加减了一次,所以不会越界
					while (secondIndex < thirdIndex && nums[secondIndex] == nums[secondIndex - 1]) secondIndex++;
					while (secondIndex < thirdIndex && nums[thirdIndex] == nums[thirdIndex + 1]) thirdIndex--;
				}
			}
		}
		return ret;
	}
};

麻烦的是去重

标签:15,nums,三数,元素,力扣,secondIndex,数组,firstNum,thirdIndex
From: https://www.cnblogs.com/yaocy/p/16591916.html

相关文章

  • [题解] HDU 5115 Dire Wolf 区间DP
    考虑先枚举所有的物品中最后拿走的,这样就分成了2个子问题,即先拿完左边的,再拿完右边的,最后拿选出的那个。令dp(i,j)表示拿完[i,j]所有物品的最小代价。你可能会说,我们拿[i,j......
  • 题解 CF1575D【Divisible by Twenty-Five】
    值域非常小,其中只有\(4\times10^6\)个数是\(25\)的倍数,因此可以暴力枚举所有位数正确的\(25\)的倍数,然后检查是否合法。检查方法就是枚举每一位,如果是数字就必须一......
  • 【.Net力扣刷题】第1302题:层数最深叶子节点的和
    题目描述来源:力扣(LeetCode)链接:https://leetcode.cn/problems/deepest-leaves-sum/给你一棵二叉树的根节点root,请你返回层数最深的叶子节点的和。题目分析本题需......
  • 洛谷 P3157 [CQOI2011]动态逆序对
    Description对于序列\(a\),它的逆序对数定义为集合\[\{(i,j)|i<j\anda_i>a_j\}\]中的元素个数。现在给出\(1\simn\)的一个排列,按照某种顺序依次删除\(m\)个......
  • 力扣|Q1834单线程CPU-SingleThreadedCPU
    Q1834SingleThreadedCPU简介给你一个二维数组tasks,用于表示n​​​​​​项从0到n-1编号的任务。其中tasks[i]=[enqueueTimei,processingTimei]意味着第i......
  • 练习10:使用while循环,接收用户input()输入一个正整数n,求1~n的和并打印,还要打印出计算公
    题干:使用while循环,接收用户input()输入一个正整数n,求1~n的和并打印,还要打印出计算公式。如:输入5,输出1+2+3+4+5=15n=int(input("enterainteger:"))res=0num_list......
  • 【搜索】力扣934:最短的桥
    在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的1形成的一个最大组。)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0的最......
  • 2022-08-15 day28 第一小组 王鸣赫
    目录Mysql数据库数据库Mysql基本操作表SQL语言SQL分类DCL(数据库控制语言)创建用户给用户授权撤销授权查看权限删除用户DDL(数据定义语言)创建表数据类型整型浮点型字符串类型......
  • 150.evaluate-reverse-polish-notation 逆波兰表达式求值
    题目本身很简单,利用stack即可,注意string转换成int->std::stoi(s),以及先判断是不是运算符,再判断是什么运算符,可以节省时间。#include<stack>#include<string>#include......
  • 【考试总结】2022-08-15
    背包将\(R_i\)缩小到颜色物品数量级别,于是\(\sumR\len\)。计算框架显然是优先队列弹出时找后继。需要满足后继总和一定大于当前元素,而且转移路径是唯一的按照次小......