leetcode 1.Two Sum 、167. Two Sum II - Input array is sorted 、15. 3Sum 、16. 3Sum Closest 、 18. 4Sum 、653. Two Sum IV - Input is a BST
1.two sum
用hash来存储数值和对应的位置索引,通过target-当前值来获得需要的值,然后再hash中寻找
错误代码1:
Input:
[3,2,4]
6
Output:
[0,0]
Expected:
[1,2]
同一个数字不能重复使用,但这个代码没排除这个问题
- class Solution {
- public:
- vector<int> twoSum(vector<int>& nums, int target) {
- vector<int> result;
- unordered_map<int,int> m;
- for(int i = ;i < nums.size();i++)
- m[nums[i]] = i;
- for(int i = ;i < nums.size();i++){
- int num = target - nums[i];
- if(m.count(num)){
- result.push_back(i);
- result.push_back(m[num]);
- break;
- }
- }
- return result;
- }
- };
错误代码2:
Input:
[3,3]
6
Output:
[]
Expected:
[0,1]
可以使用相同的数字,但不能使用同一位置的数字,这个错误代码实际上是针对相同数字,而不是同一位置的数字
- class Solution {
- public:
- vector<int> twoSum(vector<int>& nums, int target) {
- vector<int> result;
- unordered_map<int,int> m;
- for(int i = ;i < nums.size();i++)
- m[nums[i]] = i;
- for(int i = ;i < nums.size();i++){
- int num = target - nums[i];
- if(m.count(num) && num != nums[i]){
- result.push_back(i);
- result.push_back(m[num]);
- break;
- }
- }
- return result;
- }
- };
正确代码:
- class Solution {
- public:
- vector<int> twoSum(vector<int>& nums, int target) {
- vector<int> result;
- unordered_map<int,int> m;
- for(int i = ;i < nums.size();i++)
- m[nums[i]] = i;
- for(int i = ;i < nums.size();i++){
- int num = target - nums[i];
- if(m.count(num) && m[num] != i){
- result.push_back(i);
- result.push_back(m[num]);
- break;
- }
- }
- return result;
- }
- };
说白了错误2是判断数值相等,正确的写法是判断索引是否相等,就直接拒绝了这种同一个数字重复两次的情况
167. Two Sum II
数组是有序的,所以用两个指针从两侧向中间滑动就可以解决
- class Solution {
- public:
- vector<int> twoSum(vector<int>& numbers, int target) {
- vector<int> result;
- int start = ;
- int end = numbers.size() - ;
- while(start < end){
- int tmp = numbers[start] + numbers[end];
- if(tmp == target){
- result.push_back(start+);
- result.push_back(end+);
- break;
- }
- else if(tmp < target)
- start++;
- else
- end--;
- }
- return result;
- }
- };
15. 3Sum
先将数组排序,然后固定一个数,再将剩下两个数类似于two sumII的方法在数组开始和末尾进行滑动。
因为不求重复的,所以在滑动的过程中:1.在for循环中遇到相同的数字直接continue
2.在while循环中也是直接++或者--
3.另外如果当便利到的第一个数大于0了,那后面的数都会大于0,也就没有了计算的意义,所以可以直接break掉
- class Solution {
- public:
- vector<vector<int>> threeSum(vector<int>& nums) {
- vector<vector<int>> result;
- if(nums.size() < )
- return result;
- sort(nums.begin(),nums.end());
- for(int i = ;i <= nums.size() - ;i++){
- if(nums[i] > )
- break;
- if(i > && nums[i] == nums[i-])
- continue;
- int target = - nums[i];
- int start = i + ;
- int end = nums.size() - ;
- while(start < end){
- int sum = nums[start] + nums[end];
- if(sum == target){
- vector<int> res;
- res.push_back(nums[i]);
- res.push_back(nums[start]);
- res.push_back(nums[end]);
- result.push_back(res);
- while(start < end && nums[start] == nums[start+])
- start++;
- while(start < end && nums[end-] == nums[end])
- end--;
- start++;
- end--;
- }
- else if(sum < target)
- start++;
- else
- end--;
- }
- }
- return result;
- }
- };
# 这个题必须有if(nums.size() < 3),不然在nums为[]时就会报错。
原因在于https://stackoverflow.com/questions/47947956/reference-binding-to-null-pointer-of-type-value-type
size()函数返回的是无符号的,0-3会得到一个很大的数
16. 3Sum Closest
与3Sum类似的思路,先排序,然后固定其中一个值,再滑动另外两个值。3Sum相等时还需要继续移动start、end,但这个时候的比较是比较diff的最小值,滑动判断的条件是根据sum与target的值在判断
错误写法:
认为初始sum的时候计算了第一个位置,即index=0,for循环就从index=1开始,但实际上只计算了前三个,index=0还有很多其他的和的情况,比如index=0、index=1、index=3
- class Solution {
- public:
- int threeSumClosest(vector<int>& nums, int target) {
- sort(nums.begin(),nums.end());
- int sum = nums[] + nums[] + nums[];
- int res = sum;
- int diff = abs(target - sum);
- for(int i = ;i <= nums.size() - ;i++){
- int start = i + ;
- int end = nums.size() - ;
- while(start < end){
- int sum = nums[i] + nums[start] + nums[end];
- int new_diff = abs(target - sum);
- if(new_diff < diff){
- diff = new_diff;
- res = sum;
- }
- if(sum < target)
- start++;
- else
- end--;
- }
- }
- return res;
- }
- };
正确写法:
- class Solution {
- public:
- int threeSumClosest(vector<int>& nums, int target) {
- sort(nums.begin(),nums.end());
- int sum = nums[] + nums[] + nums[];
- int res = sum;
- int diff = abs(target - sum);
- for(int i = ;i <= nums.size() - ;i++){
- int start = i + ;
- int end = nums.size() - ;
- while(start < end){
- int sum = nums[i] + nums[start] + nums[end];
- int new_diff = abs(target - sum);
- if(new_diff < diff){
- diff = new_diff;
- res = sum;
- }
- if(sum < target)
- start++;
- else
- end--;
- }
- }
- return res;
- }
- };
18. 4Sum
这个题和3Sum很像,但3Sum的target是固定为0,4Sum是任意target。
两者都是先排序,3Sum是固定一个数,4Sum类似于固定两个数,即有两个数是外层for循环。两者都需要去重。
错误写法:
j > 1,这种情况就要报错:
Input:
[-1,0,1,2,-1,-4]
-1
Output:
[[-4,0,1,2]]
Expected:
[[-4,0,1,2],[-1,-1,0,1]]
j > 1这种写法会把之后所有的j > 1相同的都去掉,让后面的根本没有进行比较
- class Solution {
- public:
- vector<vector<int>> fourSum(vector<int>& nums, int target) {
- vector<vector<int>> result;
- if(nums.size() < )
- return result;
- sort(nums.begin(),nums.end());
- for(int i = ;i <= nums.size() - ;i++){
- if(i > && nums[i] == nums[i-])
- continue;
- for(int j = i + ;j <= nums.size() - ;j++){
- if(j > && nums[j] == nums[j-])
- continue;
- int start = j + ;
- int end = nums.size() - ;
- while(start < end){
- int sum = nums[i] + nums[j] + nums[start] + nums[end];
- if(sum == target){
- vector<int> res;
- res.push_back(nums[i]);
- res.push_back(nums[j]);
- res.push_back(nums[start]);
- res.push_back(nums[end]);
- result.push_back(res);
- while(start < end && nums[start] == nums[start+])
- start++;
- while(start < end && nums[end] == nums[end-])
- end--;
- start++;
- end--;
- }
- else if(sum < target)
- start++;
- else
- end--;
- }
- }
- }
- return result;
- }
- };
正确写法:
- class Solution {
- public:
- vector<vector<int>> fourSum(vector<int>& nums, int target) {
- vector<vector<int>> result;
- if(nums.size() < )
- return result;
- sort(nums.begin(),nums.end());
- for(int i = ;i <= nums.size() - ;i++){
- if(i > && nums[i] == nums[i-])
- continue;
- for(int j = i + ;j <= nums.size() - ;j++){
- if(j > + && nums[j] == nums[j-])
- continue;
- int start = j + ;
- int end = nums.size() - ;
- while(start < end){
- int sum = nums[i] + nums[j] + nums[start] + nums[end];
- if(sum == target){
- vector<int> res;
- res.push_back(nums[i]);
- res.push_back(nums[j]);
- res.push_back(nums[start]);
- res.push_back(nums[end]);
- result.push_back(res);
- while(start < end && nums[start] == nums[start+])
- start++;
- while(start < end && nums[end] == nums[end-])
- end--;
- start++;
- end--;
- }
- else if(sum < target)
- start++;
- else
- end--;
- }
- }
- }
- return result;
- }
- };
653. Two Sum IV - Input is a BST
只要是两数之和的题,一定要记得先尝试用Hash来做,这道题只不过是把数组变成了一棵二叉树而已,换汤不换药。
还是用递归的思想,遍历到每个节点的时候,用target-当前节点的值,看hash里面是否存储了值。如果没有就递归遍历,同时将此节点的值存储在hash中,以便后面的值去寻找。
- class Solution {
- public:
- bool findTarget(TreeNode* root, int k) {
- unordered_set<int> container;
- return findTarget(root,k,container);
- }
- bool findTarget(TreeNode* root,int k,unordered_set<int>& container){
- if(root == NULL)
- return false;
- int val = k - root->val;
- if(container.count(val))
- return true;
- container.insert(root->val);
- return findTarget(root->left,k,container) || findTarget(root->right,k,container);
- }
- };
一种错误写法:
如果在函数定义的时候不加引用,就会报错。这是因为,你先遍历了左子树然后才去遍历的右子树,遍历右子树的时候container应该已经存储了左子树的值才对,只有加引用才能改变container
- /**
- * Definition for a binary tree node.
- * struct TreeNode {
- * int val;
- * TreeNode *left;
- * TreeNode *right;
- * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
- * };
- */
- class Solution {
- public:
- bool findTarget(TreeNode* root, int k) {
- unordered_set<int> container;
- return findTarget(root,k,container);
- }
- bool findTarget(TreeNode* root,int k,unordered_set<int> container){
- if(!root)
- return false;
- int target = k - root->val;
- if(container.find(target) != container.end())
- return true;
- container.insert(root->val);
- return findTarget(root->left,k,container) || findTarget(root->right,k,container);
- }
- };
454. 4Sum II
https://www.cnblogs.com/grandyang/p/6073317.html
- class Solution {
- public:
- int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
- unordered_map<int,int> m;
- for(int i = ;i < A.size();i++){
- for(int j = ;j < B.size();j++){
- m[A[i] + B[j]]++;
- }
- }
- int res = ;
- for(int i = ;i < C.size();i++){
- for(int j = ;j < D.size();j++){
- int tmp = -(C[i] + D[j]);
- if(m.find(tmp) != m.end())
- res += m[tmp];
- }
- }
- return res;
- }
- };
leetcode 1.Two Sum 、167. Two Sum II - Input array is sorted 、15. 3Sum 、16. 3Sum Closest 、 18. 4Sum 、653. Two Sum IV - Input is a BST的更多相关文章
- leetcode2 Two Sum II – Input array is sorted
Two Sum II – Input array is sorted whowhoha@outlook.com Question: Similar to Question [1. Two Sum], ...
- 【LEETCODE】38、167题,Two Sum II - Input array is sorted
package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...
- Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted)
Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted) 给定一个已按照升序排列 的有序数组,找到两个数使得它们 ...
- 167. Two Sum II - Input array is sorted - LeetCode
Question 167. Two Sum II - Input array is sorted Solution 题目大意:和Two Sum一样,这里给出的数组是有序的 思路:target - nu ...
- 29. leetcode 167. Two Sum II - Input array is sorted
167. Two Sum II - Input array is sorted Given an array of integers that is already sorted in ascendi ...
- [LeetCode] Two Sum II - Input array is sorted 两数之和之二 - 输入数组有序
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
- 167. Two Sum II - Input array is sorted【easy】
167. Two Sum II - Input array is sorted[easy] Given an array of integers that is already sorted in a ...
- 167. Two Sum II - Input array is sorted@python
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
- LeetCode_167. Two Sum II - Input array is sorted
167. Two Sum II - Input array is sorted Easy Given an array of integers that is already sorted in as ...
随机推荐
- 手把手教你写一个RPC
1.1 RPC 是什么 定义:RPC(Remote Procedure Call Protocol)--远程过程调用协议 ,RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数 ...
- redis集群的远程管理与监控
一.redis集群的重要性 目前大部分的互联网平台,都会用到Redis内存数据库,以提高响应速度,提升用户使用体验. 为了实现Redis的高可用,通常都会布署Redis集群,使用Redis-Senti ...
- docker 卸载
1首先搜索已经安装的docker 安装包 [root@localhost ~]# yum list installed|grep docker 或者使用该命令 [root@localhost ~]# ...
- C#学习笔记(基础知识回顾)之值类型和引用类型
一:C#把数据类型分为值类型和引用类型 1.1:从概念上来看,其区别是值类型直接存储值,而引用类型存储对值的引用. 1.2:这两种类型在内存的不同地方,值类型存储在堆栈中,而引用类型存储在托管对上.存 ...
- JavaWeb学习总结(二):Http协议
一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的 ...
- 理解webpack4.splitChunks之其余要点
splitChunks除了之前文章提到的规则外,还有一些要点或是叫疑惑因为没有找到官方文档的明确说明,所以是通过我自己测试总结出来的,只代表我自己的测试结果,不一定正确. splitChunks.ca ...
- H5实现拍照上传功能
<input type="file" capture="camera" accept="image/*" >
- C# 按部门拆分excel文件
按照所属部门不同将excel文件拆分成多个文件 string excel_path = @"G:\zhyue\backup\2018-08-01 读取腾讯邮箱接口-获取一个月内未接收到外部邮 ...
- JDK自带工具native2ascii
背景:在做Java开发的时候,常常会出现一些乱码,或者无法正确识别或读取的文件,比如常见的validator验证用的消息资源(properties)文件就需要进行Unicode重新编码.原因是java ...
- MVC框架以及实例(补充)
此文是MVC框架以及实例(http://www.cnblogs.com/justmaomao/p/6739065.html)的补充部分 以下简单介绍简单登录的相关内容 1)在login.jsp中待提交 ...