LeetCode Two Sum&Two Sum II - Input array is sorted&3Sum&4Sum 一锅煮题解
文章目录
Two Sum
- 题意
给定一个数组,和指定一个目标和。从数组中选择两个数满足和为目标和。保证有且只有一个解。每个元素只可以用一次。 - 思路
Hash表快速查询值是否在数组中存在。
枚举一个数,查询另一个数是否存在。
注意:虽然一个元素只可以使用一次,但是数组中可以出现重复的元素。 - 复杂度
T(N)=O(N),M(N)=O(N)T(N)=O(N),M(N)=O(N)T(N)=O(N),M(N)=O(N) - 结果
Runtime: 5 ms, faster than 70.02% of Java online submissions for Two Sum.
Memory Usage: 37.5 MB, less than 100.00% of Java online submissions for Two Sum.
即(5ms, 70.02%, 37.5MB, 100.0%) - 源码
class Solution {
public int[] twoSum(int[] nums, int target) {
int []ans = new int[2];
Map<Integer,Integer> m = new HashMap<Integer,Integer>();
for (int i = 0;i < nums.length; ++i) {
if (m.containsKey(nums[i])) {
if (nums[i]*2 == target) {
ans[0] = m.get(nums[i]);
ans[1] = i;
return ans;
}
} else {
m.put(nums[i], i);
}
}
for (int i = 0;i < nums.length; ++i)
if (nums[i]*2 != target && m.containsKey(target-nums[i])) {
ans[0] = i;
ans[1] = m.get(target-nums[i]);
break;
}
return ans;
}
}
Two Sum II
- 题意
题意不变。只是输入数组有序。另外返回的下标是基于1。 - 思路
由于有序,维护一左一右两个指针,所指数的和过小,则左指针右移一格;过大,右指针左移一格;等于则返回结果。 - 复杂度
T(N)=O(N),M(N)=O(1)T(N)=O(N),M(N)=O(1)T(N)=O(N),M(N)=O(1) - 结果
(0ms, 100.0%, 36.9 MB, 100.0%) - 源码
class Solution {
public int[] twoSum(int[] nums, int target) {
// twoSumWithSortedArr
// 已经确保了答案存在
int l = 0;
int r = nums.length-1;
int t;
while (true) {
t = nums[l]+nums[r];
if (t < target)
++l;
else if (t > target)
--r;
else
return new int[] {l+1,r+1};
}
}
}
3Sum
- 题意
给定一个数组,从中选三个元素a,b,c.使得a+b+c=0.给出所有的可能的三元组(unique triplets)的集合。 - 思路1
原数组分为负数和非负数两个数组。则答案只有这些可能:- 负+非负+非负
- 非负+负+负
- 非负+非负+非负(实际上这个只能是3个0)
3个0的特殊判断。
情况1枚举负数,转换为非负数数组中的two Sum问题。
情况2同理。
- 思路2
先排序,直接枚举一个数。转化为Two Sum II问题。 - 复杂度
思路1T(N)=O(N2),M(N)=O(N)T(N)=O(N^2),M(N)=O(N)T(N)=O(N2),M(N)=O(N)
思路2T(N)=O(N2),M(N)=O(1)T(N)=O(N^2),M(N)=O(1)T(N)=O(N2),M(N)=O(1)
且考虑到思路2变成复杂度更低。毫无疑问选思路2. - 结果
(37ms, 99.61%, 48.5MB, 100.00%) - 源码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int target = 0;
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
int len = nums.length;
for (int i = 0; i+3 <= len; ++i) {
if (nums[i]*3 > target)
break;
if (i > 0 && nums[i] == nums[i-1])
continue;
int part_target = target-nums[i];
int range[] = {i+1,len-1};
while (range[0] < range[1]) {
twoSum(nums,part_target,range);
if (range[0] >= range[1])
break;
// found a ans
List<Integer> l = new ArrayList<Integer>();
l.add(nums[i]);
l.add(nums[range[0]]);
l.add(nums[range[1]]);
ans.add(l);
// move
do{
++range[0];
}while(range[0] < range[1] && nums[range[0]] == nums[range[0]-1]);
}
}
return ans;
}
public void twoSum(int[] nums, int target, int []range) {
int t;
while (range[0] < range[1]) {
t = nums[range[0]]+nums[range[1]];
if (t < target)
++range[0];
else if (t > target)
--range[1];
else
return;
}
}
}
4Sum
- 题意
类似于3Sum.只是变成4个数了。并且目标和不是固定的0,而是通过输入参数指定。 - 思路
直接循环枚举,注意控制条件以免重复。
其实应该写搜索的,但是枚举更加无脑暴力,就直接敲了。 - 复杂度
T(N)=O(N3),M(N)=O(1)T(N)=O(N^3),M(N)=O(1)T(N)=O(N3),M(N)=O(1) - 结果
(19ms, 89.95%, 40MB, 100.00%) - 源码
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
int len = nums.length;
for (int i = 0; i+4 <= len; ++i) {
if (nums[i]*4 > target)
break;
if (i > 0 && nums[i] == nums[i-1])
continue;
for (int j = i+1; j+3 <= len; ++j) {
if (nums[i]+nums[j]*3 > target)
break;
if (j > i+1 && nums[j] == nums[j-1])
continue; // 前一个数并非是a,[j]和前一个数相同,则没必要用[j]再当b
int part_target = target-nums[i]-nums[j];
int range[] = {j+1,len-1};
while (range[0] < range[1]) {
twoSum(nums,part_target,range);
if (range[0] >= range[1])
break;
// found a ans
List<Integer> l = new ArrayList<Integer>();
l.add(nums[i]);
l.add(nums[j]);
l.add(nums[range[0]]);
l.add(nums[range[1]]);
ans.add(l);
// move
do{
++range[0];
}while(range[0] < range[1] && nums[range[0]] == nums[range[0]-1]);
}
}
}
return ans;
}
public void twoSum(int[] nums, int target, int []range) {
int t;
while (range[0] < range[1]) {
t = nums[range[0]]+nums[range[1]];
if (t < target)
++range[0];
else if (t > target)
--range[1];
else
return;
}
}
}
LeetCode Two Sum&Two Sum II - Input array is sorted&3Sum&4Sum 一锅煮题解的更多相关文章
- 1. Two Sum + 15. 3 Sum + 16. 3 Sum Closest + 18. 4Sum + 167. Two Sum II - Input array is sorted + 454. 4Sum II + 653. Two Sum IV - Input is a BST
▶ 问题:给定一个数组 nums 及一个目标值 target,求数组中是否存在 n 项的和恰好等于目标值 ▶ 第 1题,n = 2,要求返回解 ● 代码,160 ms,穷举法,时间复杂度 O(n2), ...
- 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】38、167题,Two Sum II - Input array is sorted
package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...
- 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 ...
- 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], ...
- 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 ...
随机推荐
- 少量代码设计一个登录界面 - .NET CORE(C#) WPF开发
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 少量代码设计一个登录界面 - .NET CORE(C#) WPF开发 阅读导航 本文背景 代码 ...
- vue 路由过渡动效
<router-view> 是基本的动态组件,所以我们可以用 <transition> 组件给它添加一些过渡效果: <transition name="slid ...
- Sunset: dusk: Vulnhub Walkthrough
靶机链接: https://www.vulnhub.com/entry/sunset-dusk,404/ 主机IP扫描: IP端口扫描: 21 端口 pyftpdlib 1.5.5 版本漏洞 25 ...
- sklearn使用小贴士
1 sklearn简介 Scikit-learn(sklearn)是机器学习中的第三方模块,封装了常用的机器学习算法,涉及回归.降维.分类以及聚类等,提供python接口. 虽然sklearn容纳的算 ...
- 【DTOJ】1001:长方形周长和面积
DTOJ 1001:长方形周长和面积 解题报告 2017.11.05 第一版 ——由翱翔的逗比w原创 题目信息: 题目描述 已知长方形的长和宽,求长方形的周长和面积? 输入 一行:空格隔开的两个整 ...
- linux 开机自启动redis服务
[Unit] Description=The redis-server Process Manager Documentation=https://redis.io/ After=network.ta ...
- matlab 中 find() 函数用法
一. 功能: 寻找非零元素的索引和值 二.相关函数语法: ind = find(X) ind = find(X, k) ind = find(X, k, 'first') ind = find(X, ...
- ES6常用语法(二)
arrow functions (箭头函数) 函数的快捷写法.不需要 function 关键字来创建函数,省略 return 关键字,继承当前上下文的 this 关键字 // ES5 var arr1 ...
- js遇到代码出现问题时如何调试代码
单步跟踪调试 debugger; 控制台watch功能查看变量当前值 进入函数操作 随着不断点击,不停进行循环,指定变量的值也在发生改变 添加断点 跳入跳出函数 throw new Error() 主 ...
- 00 - PXE | 环境准备
00 - PXE | 环境准备 TFTP PXE 1. TFTP服务搭建 安装环境Centos7.3 1.1 安装 # yum install xinetd # yum install tftp # ...