当前位置:网站首页>LeetCode三数之和问题
LeetCode三数之和问题
2022-07-26 09:15:00 【爱笑的tiger】
1.两数之和问题
介绍:给定一个整数数组和一个目标值target,在数组中找出和为目标值target的那两个整数,并返回他们的数组下标,答案不能重复出现。
示例:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
解法1:暴力解法,双重循环,暴力枚举,时间复杂度O(n^2),空间复杂度为O(1)
class Solution {
public int[] twoSum(int[] nums, int target) {
int n = nums.length;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
return new int[0];
}
}
解法2:使用哈希表,可以将寻找 target - x
的时间复杂度降低到从 O(N) 降低到 O(1)。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; ++i) {
if (hashtable.containsKey(target - nums[i])) {
return new int[]{hashtable.get(target - nums[i]), i};
}
hashtable.put(nums[i], i);
}
return new int[0];
}
}
2.三数之和问题
介绍:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]
解法:排序+双指针
时间复杂度:O(N^2)其中 N 是数组nums 的长度。
空间复杂度:O(logN)。我们忽略存储答案的空间,额外的排序的空间复杂度为 O(log N)。然而我们修改了输入的数组nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了 nums 的副本并进行排序,空间复杂度为 O(N)。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<List<Integer>>();
// 枚举 a
for (int first = 0; first < n; ++first) {
// 需要和上一次枚举的数不相同
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for (int second = first + 1; second < n; ++second) {
// 需要和上一次枚举的数不相同
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while (second < third && nums[second] + nums[third] > target) {
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
List<Integer> list = new ArrayList<Integer>();
list.add(nums[first]);
list.add(nums[second]);
list.add(nums[third]);
ans.add(list);
}
}
}
return ans;
}
}
3.最接近的三数之和
介绍:给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。返回这三个数的和。
假定每组输入只存在恰好一个解。
示例:
输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
解法:排序+双指针
时间复杂度:O(N^2)其中 N 是数组 nums 的长度。我们首先需要 O(NlogN) 的时间对数组进行排序,随后在枚举的过程中,使用一重循环 O(N) 枚举 aa,双指针O(N) 枚举 bb 和 cc,故一共是 O(N^2)
空间复杂度:O(logN)。排序需要使用O(logN) 的空间。然而我们修改了输入的数组 nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了 nums 的副本并进行排序,此时空间复杂度为O(N)。
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int n = nums.length;
int best = 10000000;
// 枚举 a
for (int i = 0; i < n; ++i) {
// 保证和上一次枚举的元素不相等
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
// 使用双指针枚举 b 和 c
int j = i + 1, k = n - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
// 如果和为 target 直接返回答案
if (sum == target) {
return target;
}
// 根据差值的绝对值来更新答案
if (Math.abs(sum - target) < Math.abs(best - target)) {
best = sum;
}
if (sum > target) {
// 如果和大于 target,移动 c 对应的指针
int k0 = k - 1;
// 移动到下一个不相等的元素
while (j < k0 && nums[k0] == nums[k]) {
--k0;
}
k = k0;
} else {
// 如果和小于 target,移动 b 对应的指针
int j0 = j + 1;
// 移动到下一个不相等的元素
while (j0 < k && nums[j0] == nums[j]) {
++j0;
}
j = j0;
}
}
}
return best;
}
}
4.四数之和
介绍:给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复)
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案。示例:
输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
解法:排序+双指针
时间复杂度:O(n^3),其中 nn 是数组的长度。排序的时间复杂度是 O(n \log n)O(nlogn),枚举四元组的时间复杂度是 O(n^3)因此总时间复杂度为 O(n^3+nlog n)=O(n^3)
空间复杂度:O(logn),其中 nn 是数组的长度。空间复杂度主要取决于排序额外使用的空间。此外排序修改了输入数组 nums,实际情况中不一定允许,因此也可以看成使用了一个额外的数组存储了数组 nums 的副本并排序,空间复杂度为O(n)。
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> quadruplets = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 4) {
return quadruplets;
}
Arrays.sort(nums);
int length = nums.length;
for (int i = 0; i < length - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
break;
}
if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
continue;
}
for (int j = i + 1; j < length - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
break;
}
if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
continue;
}
int left = j + 1, right = length - 1;
while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
quadruplets.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
left++;
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}
return quadruplets;
}
}
总结:上面三数之和问题是面试常考,需要牢记,上面解法思路大致一样。
边栏推荐
- Object type collections are de duplicated according to the value of an attribute
- Two tips for pycharm to open multiple projects
- pycharm 打开多个项目的两种小技巧
- Pytoch realizes logistic regression
- volatile 靠的是MESI协议解决可见性问题?(下)
- Announcement | FISCO bcos v3.0-rc4 is released, and the new Max version can support massive transactions on the chain
- 2B和2C
- NPM add source and switch source
- Babbitt | metauniverse daily must read: does the future of metauniverse belong to large technology companies or to the decentralized Web3 world
- PHP和MySQL获取week值不一致的处理
猜你喜欢
李沐d2l(四)---Softmax回归
CF1481C Fence Painting
Elastic APM安装和使用
Horizontal comparison of the data of the top ten blue chip NFTs in the past half year
volatile 靠的是MESI协议解决可见性问题?(下)
Stm32+mfrc522 completes IC card number reading, password modification, data reading and writing
Li Mu D2L (IV) -- softmax regression
Form form
Two tips for pycharm to open multiple projects
JDBC database connection pool (Druid Technology)
随机推荐
mysql函数
Probability model in machine learning
堆外内存的使用
对象型的集合按某个属性的值进行去重
187. Repeated DNA sequence
Day06 operation -- addition, deletion, modification and query
(2006, MySQL server has gone away) problem handling
2B and 2C
【Mysql】一条SQL语句是怎么执行的(二)
Espressif plays with the compilation environment
"Could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32"
Pat grade a a1076 forwards on Weibo
Innovus卡住,提示X Error:
HBuilderX 运行微信开发者工具 “Fail to open IDE“报错解决
本地缓存
Does volatile rely on the MESI protocol to solve the visibility problem? (next)
2022流动式起重机司机考试题模拟考试题库模拟考试平台操作
Datax的学习笔记
Zipkin安装和使用
Clean the label folder