• 快慢指针之原地处理数组/链表


    快慢指针之原地处理数组/链表

    leetcode26.删除排序数组中的重复项

    由于数组已经排序,所以重复的元素一定连在一起,找出它们并不难,但如果毎找到一个重复元素就立即删除它,就是在数组中间进行删除操作,整个时间复杂度是会达到 O(N^2)。
    我们让慢指针slow走在后面,快指针fast走在前面探路,找到一个不重复的元素就告诉slow并让slow前进一步。这样当fast指针遍历完整个数组nums后,nums[0..slow]就是不重复元素

    int removeDuplicates(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        int slow = 0, fast = 0;
        while (fast < nums.length) {
            if (nums[fast] != nums[slow]) {
                slow++;
                // 维护 nums[0..slow] 无重复
                nums[slow] = nums[fast];
            }
            fast++;
        }
        // 数组长度为索引 + 1
        return slow + 1;
    }
    

    再简单扩展一下,如果给你一个有序链表,如何去重呢?这是力扣第 83 题,其实和数组去重是一模一样的,唯一的区别是把数组赋值操作变成操作指针而已:

    ListNode deleteDuplicates(ListNode head) {
        if (head == null) return null;
        ListNode slow = head, fast = head;
        while (fast != null) {
            if (fast.val != slow.val) {
                // nums[slow] = nums[fast];
                slow.next = fast;
                // slow++;
                slow = slow.next;
            }
            // fast++
            fast = fast.next;
        }
        // 断开与后面重复元素的连接
        slow.next = null;
        return head;
    }
    

    leetcode27.移除元素

    如果fast遇到需要去除的元素,则直接跳过,否则就告诉slow指针,并让slow前进一步。

    int removeElement(int[] nums, int val) {
        int fast = 0, slow = 0;
        while (fast < nums.length) {
            if (nums[fast] != val) {
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
    

    注意这里和有序数组去重的解法有一个重要不同,我们这里是先给nums[slow]赋值然后再给slow++,这样可以保证nums[0..slow-1]是不包含值为val的元素的,最后的结果数组长度就是slow

    leetcode283.

    题目让我们将所有 0 移到最后,其实就相当于移除nums中的所有 0,然后再把后面的元素都赋值为 0 即可。

    void moveZeroes(int[] nums) {
        // 去除 nums 中的所有 0
        // 返回去除 0 之后的数组长度
        int p = removeElement(nums, 0);
        // 将 p 之后的所有元素赋值为 0
        for (; p < nums.length; p++) {
            nums[p] = 0;
        }
    }
    
    // 见上文代码实现
    int removeElement(int[] nums, int val);
    
  • 相关阅读:
    css 自动调整不同 大小的图片变成一定大小
    myeclipse 修改html 报错
    js 中json的使用
    对比两个文件相似度 余弦算法
    andriod 解包
    http post/get 请求
    VXLAN 静态隧道实现同网段通信
    网络设备巡检命令
    IPv6
    Cisco ASA 调整terminal屏幕
  • 原文地址:https://www.cnblogs.com/shiji-note/p/14397099.html
Copyright © 2020-2023  润新知