一 LC136.只出现过一次的数字
题目要求:
给你一个 非空 整数数组
nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
思路分析:
这道题目其实好像也是很经典的一道题目,经常会出现在面试中。看到题目其实很多人第一反应就是哈希或者暴力(比如我...),但是本题要求了时间复杂度和空间复杂度。这时就要用到我们从学习编程语言第一课就学习过,但是往往被我们遗忘的位运算了。这道题的难度也就在这里,只要能想到用位运算,就没什么难点了。
异或运算的特性:
x ^ x = 0
:任何数字与自己异或结果为 0。x ^ 0 = x
:任何数字与 0 异或结果为自己。- 满足交换律和结合律。
本题中,我们只要遍历数组中的每个元素,将它们依次与 result
进行异或操作。由于相同的数字异或结果为 0,最终 result
就是那个只出现一次的数字 。
完整代码示例:
class Solution {
public int singleNumber(int[] nums) {
int result = 0;
// 遍历数组,使用异或运算
for (int num : nums) {
result ^= num;
}
return result;
}
}
二 LC169.多数元素
题目要求:
给定一个大小为
n
的数组nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于⌊ n/2 ⌋
的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
思路分析:
我们假设数组中总存在一个“多数元素”,它出现的次数比其他所有元素加起来还要多,因此可以通过消除不同的元素,最终得到多数元素。
首先我们用一个变量 candidate
来存储当前的候选多数元素,并用 count
来统计当前候选元素的支持度。当遇到和 candidate
相同的元素时,count
增加;遇到不同的元素时,count
减少。当 count
为 0 时,说明当前候选元素已经被“抵消”了,需要重新选择一个候选多数元素。最终,candidate
就是多数元素。
完整代码示例:
class Solution {
public int majorityElement(int[] nums) {
int candidate = nums[0];
int count = 1;
// 选出候选多数元素
for (int i = 1; i < nums.length; i++) {
if (nums[i] == candidate) {
count++;
} else {
count--;
}
if (count == 0) {
candidate = nums[i];
count = 1;
}
}
return candidate;
}
}
三 LC75.颜色分类
题目要求:
给定一个包含红色、白色和蓝色、共
n
个元素的数组nums
,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数
0
、1
和2
分别表示红色、白色和蓝色。必须在不使用库内置的 sort 函数的情况下解决这个问题。
思路分析:
我们可以维护三个指针:
low:用于表示0的边界(红色区域的右边界)。
mid:用于扫描数组。
high:用于表示2的边界(蓝色区域的左边界)。
mid指向数组首个元素,high执行数组末尾。遍历数组,当mid指向的元素等于0时,将mid和low位置的元素交换,并将low和mid都向右移动;当
nums[mid] == 1时,只移动
mid。当mid指向的元素等于2时,将mid和high位置的元素交换,并将mid向右移动。直到mid大于high时,结束循环。
完整代码示例:
class Solution {
public void sortColors(int[] nums) {
int low = 0;
int mid = 0;
int high = nums.length - 1;
// 遍历数组
while (mid <= high) {
if (nums[mid] == 0) {
// 如果遇到0,将它交换到low位置,并将low和mid指针都向右移动
swap(nums, low, mid);
low++;
mid++;
} else if (nums[mid] == 1) {
// 如果遇到1,直接将mid指针向右移动
mid++;
} else if (nums[mid] == 2) {
// 如果遇到2,将它交换到high位置,并将high指针向左移动
swap(nums, mid, high);
high--;
}
}
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}