Top Interview 150
  • 👋Welcome!
  • 数组-字符串
    • 合并两个有序数组
    • 移除元素
    • 删除有序数组中的重复项
    • 删除有序数组中的重复项II
    • 买卖股票的最佳时机
    • 买卖股票的最佳时机II
    • 多数元素
    • 罗马数字转整数
    • 轮转数组
    • 跳跃游戏
    • 跳跃游戏II
    • 找出字符串中第一个匹配项的下标
    • 柠檬水找零
    • 最长回文子串
    • H指数
    • O(1)时间插入、删除和获取随机元素
    • 除自身以外数组的乘积
    • 加油站
    • 分发糖果
    • 最后一个单词的长度
    • 整数转罗马数字
    • 最长公共前缀
    • 反转字符串重的单词
    • N字形变换
    • 文本左右对齐
  • 双指针
    • 验证回文串
    • 判断子序列
    • 两数之和 II - 输入有序数组
    • 三数之和
    • 盛最多水的容器
  • 滑动窗口
    • 长度最小的子数组
    • 无重复字符的最长子串
    • 串联所有单词的子串
    • 最小覆盖子串
  • 矩阵
    • 有效的数独
    • 螺旋矩阵
    • 旋转矩阵
    • 矩阵置零
    • 生命游戏
  • 哈希表
    • 赎金信
    • 两数之和
    • 快乐数
    • 同构字符串
    • 单词规律
    • 有效的字母异位词
    • 字母异位词分组
    • 存在重复元素 II
    • 最长连续序列
  • 区间
    • 汇总区间
    • 合并区间
    • 插入区间
    • 用最少数量的箭箭引爆气球
  • 栈
    • 有效的括号
    • 简化路径
    • 最小栈
    • 基本计算器
    • 逆波兰表达式求值
  • 链表
    • 环形链表
    • 两数相加
    • 合并两个有序链表
    • 复制带随机指针的链表
    • 反转链表 II
    • 删除链表的倒数第 N 个结点
    • 删除排序链表中的重复元素
    • 旋转链表
    • 分隔链表
    • LRU 缓存
    • K个一组翻转链表
  • 树
    • 二叉树的最大深度
    • 相同的树
    • 翻转二叉树
    • 对称二叉树
    • 填充每个节点的下一个右侧节点指针
    • 二叉树展开为链表
    • 从前序和中序遍历序列构造二叉树
    • 求根节点到叶节点数字之和
    • 二叉树中最大路径和
    • 二叉搜索树迭代器
    • 完全二叉树的节点个数
    • 二叉树的最近公共祖先
    • 二叉树的右视图
    • 二叉树的层平均值
    • 二叉树的层序遍历
    • 二叉树的锯齿形层序遍历
    • 二叉搜索树的最小绝对差
    • 二叉搜索树中第K小的元素
    • 验证二叉搜索树
  • 图
    • 岛屿数量
    • 被围绕的区域
    • 克隆图
    • 除法求值
    • 课程表
    • 课程表 II
  • 广度优先搜索
    • 蛇梯棋
    • 最小基因变化
    • 单词接龙
  • 深度优先搜索
  • 字典树
    • 实现 Trie (前缀树)
    • 添加与搜索单词 - 数据结构设计
    • 单词搜索 II
  • 回溯
    • 电话号码的字母组合
    • 组合
    • 全排列
    • 组合总和
    • 括号生成
    • n皇后问题II
    • 单词搜索
  • 分治
    • 将有序数组转换为二叉搜索树
    • 排序链表
  • Kadane 算法
    • 环形子数组的最大和
    • 最大子数组和
  • 二分查找
    • 搜索插入位置
    • 寻找峰值
    • 搜索二维矩阵
  • 堆
  • 位运算
    • 二进制求和
    • 颠倒二进制位
    • 位1的个数
    • 只出现一次的数字
    • 只出现一次的数字 II
    • 数字范围按位与
  • 数学
    • 回文数
    • 阶乘后的零
    • 加一
    • x 的平方根
    • Pow(x, n)
    • 直线上最多的点数
  • 动态规划
    • 爬楼梯
    • 打家劫舍
    • 单词拆分
    • 最长递增子序列
    • 零钱兑换
    • 三角形最小路径和
    • 最小路径和
    • 不同路径 II
    • 最长回文子串
    • 交错字符串
    • 编辑距离
由 GitBook 提供支持
在本页
  • 解题思路:
  • 复杂度分析

这有帮助吗?

在GitHub上编辑
  1. 双指针

三数之和

上一页两数之和 II - 输入有序数组下一页盛最多水的容器

最后更新于1年前

这有帮助吗?

题目链接:

解题思路:

排序 + 双指针

  1. 判断数组 nums 的长度是否小于 3,如果是,则直接返回 nil

  2. 对数组 nums 进行排序

  3. 遍历数组 nums 中的每个数字,在循环中,函数首先判断当前数字是否大于 0,如果是,则说明三数之和一定大于 0,直接结束循环

  4. 使用双指针来查找数组中所有和为当前数字的相反数的不重复的三元组,在双指针遍历的过程中,判断当前三个数字的和与 0 的大小关系,并根据不同的情况来移动指针

  5. 去重:首先,在遍历数组 nums 的过程中,如果当前数字与前一个数字相同,则直接跳过,避免重复计算。其次,在找到一个和为 0 的三元组后,函数会继续移动指针,直到找到下一个不同的数字,避免重复计算

func threeSum(nums []int) [][]int {
	if len(nums) < 3 {
		return nil
	}

	// 排序
	quickSort(nums, 0, len(nums)-1)

	ans := make([][]int, 0)
	for i := 0; i < len(nums)-2; i++ {
		// 如果当前数字大于0,则三数之和一定大于0,所以结束循环
		if nums[i] > 0 {
			break
		}
		// 去重
		if i > 0 && nums[i] == nums[i-1] {
			continue
		}

		// 双指针
		left, right := i+1, len(nums)-1
		for left < right {
			sum := nums[i] + nums[left] + nums[right]

			switch {
			case sum == 0:
				ans = append(ans, []int{nums[i], nums[left], nums[right]})
				// 去重
				for left < right && nums[left] == nums[left+1] {
					left++
				}
				// 去重
				for left < right && nums[right] == nums[right-1] {
					right--
				}
				left++
				right--
			case sum < 0:
				left++
			case sum > 0:
				right--
			}
		}
	}

	return ans
}

func quickSort(nums []int, left, right int) {
	if left < right {
		pivot := partition(nums, left, right)
		quickSort(nums, left, pivot-1)
		quickSort(nums, pivot+1, right)
	}
}

func partition(nums []int, left, right int) int {
	pivot := nums[left]
	for left < right {
		for left < right && nums[right] >= pivot {
			right--
		}
		nums[left] = nums[right]
		for left < right && nums[left] <= pivot {
			left++
		}
		nums[right] = nums[left]
	}

	nums[left] = pivot

	return left
}

复杂度分析

时间复杂度: 时间复杂度为 O(n2)O(n^2)O(n2),其中 nnn 是数组 nums 的长度。函数中有两个循环,外层循环遍历了数组 nums 中的每个数字,内层循环使用双指针遍历数组中的剩余数字。在内层循环中,左指针和右指针分别从数组的两端开始向中间移动,因此内层循环的时间复杂度为 O(n)O(n)O(n)。因此,函数的总时间复杂度为 O(n2)O(n^2)O(n2)

空间复杂度: 只使用了常数个变量,因此空间复杂度为 O(1)O(1)O(1),函数只使用了常数个变量来存储中间结果,没有使用额外的空间

https://leetcode.cn/problems/3sum/