解题思路
由于数组是非严格递增的,重复的元素必然是相邻的。我们可以用两个指针:
- 慢指针 prev:标记'已处理的无重复元素'的最后一个位置。
- 快指针 curr:遍历数组,寻找新的、未出现过的元素。

结合示例 1(输入 nums = [1,1,2])拆解解题过程:
步骤 1:初始化指针
- 慢指针 prev 初始化为 0(指向数组第一个元素 1)。
- 快指针 curr 初始化为 1(从第二个元素开始遍历)。
步骤 2:第一次循环(curr = 1)
此时 nums[curr] = 1,nums[prev] = 1,两者相等。
- 因为元素重复,不需要更新 nums,仅将 curr 后移(curr = 2)。
- 数组状态仍为 [1, 1, 2]。
步骤 3:第二次循环(curr = 2)
此时 nums[curr] = 2,nums[prev] = 1,两者不相等。
- 先将 prev 后移(prev = 1)。
- 把 nums[curr] 的值(2)赋给 nums[prev],此时数组变为 [1, 2, 2]。
- 再将 curr 后移(curr = 3),此时 curr 超出数组长度,循环结束。
步骤 4:返回结果
最终 prev = 1,无重复元素的数量为 prev + 1 = 2,与示例输出一致。数组的前 2 个元素为 [1, 2],满足题目要求。
尤其注意:慢指针 prev 最终指向的是'无重复元素区域'的最后一个元素的索引,需要返回的是无重复元素的数量。
通过这样的步骤,双指针法在原地完成了重复元素的删除,同时保证了时间复杂度为 O(n)、空间复杂度为 O(1),是该问题的最优解法。
二、只出现一次的数字

写这道题要清楚异或运算的特性:异或运算(^)是基于二进制位的操作,规则是:对应二进制位相同则为 0,不同则为 1。
// 3 的二进制:011(8 位表示为 00000011)
// 5 的二进制:101(8 位表示为 00000101)
// 合并结果为 00000110,即十进制的 6。所以 3 ^ 5 = 6
性质 1:相同的数异或,结果为 0。例如 2 ^ 2 = 0,5 ^ 5 = 0。 性质 2:0 和任意数异或,结果为这个数本身。例如 0 ^ 3 = 3,0 ^ 99 = 99
异或元素还满足:
- 交换律:a ^ b = b ^ a(异或的顺序不影响结果)。
- 结合律:(a ^ b) ^ c = a ^ (b ^ c)(可以任意调整异或的组合顺序)。
// 4 ^ 1 ^ 2 ^ 1 ^ 2 = (1 ^ 1) ^ (2 ^ 2) ^ 4 = 0 ^ 0 ^ 4 = 4



