文章目录

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

    原数组分为负数和非负数两个数组。则答案只有这些可能:

    1. 负+非负+非负
    2. 非负+负+负
    3. 非负+非负+非负(实际上这个只能是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. 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), ...

  2. Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted)

    Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted) 给定一个已按照升序排列 的有序数组,找到两个数使得它们 ...

  3. 167. Two Sum II - Input array is sorted - LeetCode

    Question 167. Two Sum II - Input array is sorted Solution 题目大意:和Two Sum一样,这里给出的数组是有序的 思路:target - nu ...

  4. 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 ...

  5. 【LEETCODE】38、167题,Two Sum II - Input array is sorted

    package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...

  6. 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 ...

  7. 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], ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. mysql出现 Unknown column 'Password' in 'field list'

    linux安装了mysql之后初始化密码获取:出现了下面的内容,密码很尴尬,无法用root登录: grep 'temporary password' /var/log/mysqld.log [Note ...

  2. C#基础知识学习(1)方法的重写和隐藏

    做了1年多了C#,发现些项目过程中很多基础东西都不是很清晰,基础不够牢固.现在开始复习基础知识并做重点记录 方法需要被重写的时候,可以在方法前加入virtual使方法变成虚方法. 这样我们可以重新写个 ...

  3. 【WPF学习】第四十九章 基本动画

    在前一章已经学习过WPF动画的第一条规则——每个动画依赖于一个依赖项属性.然而,还有另一个限制.为了实现属性的动态化(换句话说,使用基于时间的方式改变属性的值),需要有支持相应数据类型的动画类.例如, ...

  4. 传智播客C++视频学习笔记(5)

    #include <iostream> using namespace std; void swapInt(int& a, int& b) { int temp = a; ...

  5. Ream--(objc)写事务精简方案

    Ream--(objc)写事务精简方案 地址: REALM-- Realm官方提供的的写事务有两种方式: A[realm beginWriteTransaction]; // ... [realm c ...

  6. 查找第K大的值

    这种题一般是给定N个数,然后N个数之间通过某种计算得到了新的数列,求这新的数列的第K大的值 POJ3579 题意: 用$N$个数的序列$x[i]$,生成一个新序列$b$. 新的序列定义为:对于任意的$ ...

  7. 如何在 vue 中添加权限控制管理?---vue中文社区

    前言 在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来限制每个用户的操作.作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的限制. 需求 因为 ...

  8. Binder 原理整理

    linux进程间通信方式 1. 管道 管道的实质是一个内核缓冲区,管道的作用正如其名,需要通信的两个进程在管道的两端,进程利用管道传递信息.管道对于管道两端的进程而言,就是一个文件,但是这个文件比较特 ...

  9. springcloud服务已经关闭但是Eureka显示服务状态一直为UP

    问题: 最近遇到一个很奇怪的问题,就是使用springcloud的时候,服务明明已经停止,但是在eureka中一直显示此服务状态为UP,这样就导致了请求再次过来的时候被分发到已经停止的服务上,其实这是 ...

  10. IBM x3250m5安装redhat 6.5 加载raid卡驱动

    原文地址:http://www.i5i6.net/post/118.html 1. 下载对应raid卡驱动 for redhat6.5 x64(如本次x3250 m5 c100阵列卡驱动 lsi_dd ...