技巧(5) --hot 100 in leetcode
只出现一次的数字
算法概述
本题要求为在给出的由一个出现一次的数字和其他出现两次的数字中找到那个出现一次的(要求时间复杂度为O(n),空间复杂度为O(1))。使用 位运算 解决。
JAVA
1 | class Solution { |
C++
1 | // 异或运算是一样的 |
注意
异或运算^的运算规律如下:
- 与相同数异或,得到0
- 与0异或,得到自身( 等同于二进制的数中的每一位都与0异或,那么每一位异或得到的就是原本的0或1 )
位运算也很重要
多数元素
算法概述
本题要求为返回其中多数元素(出现频次大于一半),要求时间复杂度和空间复杂度与上题一致。使用Boyer-Moore 投票算法。
JAVA
1 | class Solution { |
C++
1 | // 总体思路一致 |
注意
众数的频次绝对会比其他所有的数频次加起来高(大于一半),所以不管怎么排列,只要存在众数,count本质上是众数的频次减去其他所有数的频次,一定为正,且所属的candidate也会在遍历完后成为众数。
颜色分类
算法概述
本题要求将相同颜色 原地 排列相邻,不同颜色之间遵照顺序(一共三种颜色,用012表示),复杂度要求与上题一致。使用 双指针 解决。
JAVA
1 | class Solution { |
C++
1 | // 思路一致,用vector,不用指针,数字索引就行 |
注意
p0指向0区末尾,p1指向1区末尾。当遇到0且p0小于p1时,交换当前索引和p1指针,是为了将1区扩张,恢复被0挤走的空间,这个交换的一定是1,是 原来占据0区的1 ,在0交换回来后把1放在了被交换的位置,再与p1交换回来填充在尾部。
下一个排列
算法概述
本题要求为找出给出数组的下一个排列(就是比当前数大的其他排列中最小的那个排列),要求原地,空间复杂度要求常数。也就是要 找最靠右的一个顺序对,左边的是小的,右边的是大的,然后交换它们 。
- 时间复杂度为O(n):两次遍历
JAVA
1 | class Solution { |
C++
1 | // 一样的思路 |
注意
主要难点是理解题目。还有要记得 反转 。
while (i >= 0 && nums[i] >= nums[i + 1]):这个循环是用于 将升序遍历完while (j >= 0 && nums[i] >= nums[j]):这个循环是用于 将小于i值的元素遍历完
非常神奇的写法
寻找重复数
算法概述
本题要求为在给定的只有一个重复数的数组中找到那个重复数,不修改原数组且空间复杂度为常数级。可以用位运算解决,但更快的还是 快慢指针 。但这个 快慢指针 是基于 索引 的,还不是基于速度的。
- 时间复杂度为O(n)
JAVA
1 | class Solution { |
C++
1 | // 一样的 |
注意
解法核心在于 基于索引移动跳转 ,因为有重复元素,所以一定能通过跳转索引的方式找到环。然后,可以确定的是,快慢指针此时相遇时 是在环内 ,因为值一样,但不能确定入环点。此时需要 将慢指针放回起始点,不动快指针 ,让它们 同频移动 ,就会在入环点相遇(可参考“环形链表II”的计算)。注意,第一个循环 不能确定重复值 ,因为是 索引形成的环 。
- Title: 技巧(5) --hot 100 in leetcode
- Author: tobegold574
- Created at : 2024-11-28 00:19:45
- Updated at : 2025-10-05 21:36:05
- Link: https://tobegold574.me/2024/11/28/算法/LeetCode/hot-100/技巧-5-hot-100-in-leetcode/
- License: This work is licensed under CC BY-NC-SA 4.0.