首页 数字经济

高效算法:双指针法优化数组去重,告别冗余循环

分类:数字经济
字数: (6299)
阅读: (1501)
内容摘要:高效算法:双指针法优化数组去重,告别冗余循环,

在日常开发中,我们经常会遇到需要对数组进行去重的场景,特别是处理来自数据库或者外部接口的数据时。例如,一个排序后的用户ID数组中可能存在重复项,而我们需要提取唯一的ID列表。最直观的方法是使用嵌套循环,但这种方法的时间复杂度为 O(n^2),效率较低。今天我们来探讨如何使用双指针法,将数组去重的效率提升到 O(n)。这种优化在处理大数据量的数组时,效果尤为显著。

高效算法:双指针法优化数组去重,告别冗余循环

问题场景重现

假设我们有一个已经排序的整数数组 nums = [1, 1, 2, 2, 3, 4, 4, 5]。我们的目标是原地修改这个数组,使得每个元素只出现一次,并返回新数组的长度。也就是说,修改后的数组应该是 [1, 2, 3, 4, 5],返回长度为 5。注意,我们只能使用 O(1) 的额外空间。

高效算法:双指针法优化数组去重,告别冗余循环

双指针法原理剖析

双指针法的核心思想是使用两个指针,一个慢指针 i 和一个快指针 j。慢指针 i 指向已经处理过的、不重复的元素的最后一个位置。快指针 j 用于遍历整个数组,寻找与 nums[i] 不同的元素。如果 nums[j]nums[i] 不同,则将 nums[j] 复制到 nums[i+1] 的位置,并将 i 向前移动一位。这样,我们就可以在 O(n) 的时间复杂度内完成数组去重。

高效算法:双指针法优化数组去重,告别冗余循环

代码实现(Java)

public class RemoveDuplicates {
    public int removeDuplicates(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }

        int i = 0; // 慢指针,指向已处理的不重复元素的最后一个位置
        for (int j = 1; j < nums.length; j++) { // 快指针,遍历数组
            if (nums[j] != nums[i]) { // 如果快指针指向的元素与慢指针指向的元素不同
                i++; // 慢指针向前移动一位
                nums[i] = nums[j]; // 将快指针指向的元素复制到慢指针的下一个位置
            }
        }

        return i + 1; // 返回新数组的长度
    }

    public static void main(String[] args) {
        RemoveDuplicates rd = new RemoveDuplicates();
        int[] nums = {1, 1, 2, 2, 3, 4, 4, 5};
        int len = rd.removeDuplicates(nums);
        System.out.println("New length: " + len);
        for (int k = 0; k < len; k++) {
            System.out.print(nums[k] + " ");
        }
        System.out.println();
    }
}

代码实现(Python)

class Solution:
    def removeDuplicates(self, nums: list[int]) -> int:
        if not nums:
            return 0

        i = 0 # 慢指针
        for j in range(1, len(nums)): # 快指针
            if nums[j] != nums[i]:
                i += 1
                nums[i] = nums[j]
        return i + 1

# 示例
nums = [1, 1, 2, 2, 3, 4, 4, 5]
solution = Solution()
length = solution.removeDuplicates(nums)
print("New length:", length)
print(nums[:length])

实战避坑经验总结

  1. 空数组处理:在实现算法之前,一定要考虑数组为空的情况,避免空指针异常。Java 代码中,我们首先判断了 nums == null || nums.length == 0,如果为空则直接返回 0。
  2. 数组越界:在移动慢指针 i 之前,一定要确保 i 的值在有效范围内,否则会发生数组越界异常。
  3. 原地修改:题目要求原地修改数组,所以我们不能创建新的数组。在双指针移动的过程中,要时刻注意不要覆盖掉有用的数据。
  4. 理解返回值:该方法返回的是去重后数组的长度,而不是去重后的数组。如果需要获取去重后的数组,需要根据返回的长度截取原始数组。
  5. 服务器高并发场景:假设这个去重操作是后端 API 的一部分,需要考虑高并发场景下的性能。可以结合 Nginx 做负载均衡,使用 Redis 缓存去重后的结果,避免频繁访问数据库。Nginx 的反向代理功能可以将请求分发到多台服务器上,提高系统的并发连接数和吞吐量。也可以考虑使用像宝塔面板之类的工具来简化服务器的管理。

希望这个例子能帮助你更好地理解双指针法在数组去重中的应用。掌握这种方法,可以有效地提升代码的性能,特别是在处理大数据量的数组时。

高效算法:双指针法优化数组去重,告别冗余循环

高效算法:双指针法优化数组去重,告别冗余循环

转载请注明出处: 代码旅人

本文的链接地址: http://m.acea2.store/blog/670011.SHTML

本文最后 发布于2026-04-21 13:42:01,已经过了6天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 烤冷面 1 天前
    讲得真透彻!双指针法确实是优化数组操作的利器,学到了。
  • i人日记 1 天前
    代码示例很清晰,Java和Python都有,赞!不过在高并发场景下,Redis缓存失效了怎么办呢?有没有什么容错方案?
  • 螺蛳粉真香 4 天前
    讲得真透彻!双指针法确实是优化数组操作的利器,学到了。