其他分享
首页 > 其他分享> > 6.原地修改数组

6.原地修改数组

作者:互联网

原地修改数组

对于数组,尾部插入、删除比较高效,时间复杂度是O(1),但是如果在中间或者开头插入、删除元素,就会涉及数据的迁移,时间复杂度是O(N),效率较低。

有序数组/链表去重

由于数组已经排序,重复的元素一定连在一起,找到不难,但如果每找到一个重复元素就立刻删除,整个时间复杂度会达到O(N^2)

这种需求在数组相关的算法题中非常常见,通常解法就是双指针技巧中的快慢指针

让慢指针slow走在后面,快指针fast走在前面探路,找到一个不重复的元素就告诉slow并让slow前进一步。当fast指针遍历完整个数组nums后,nums[0,slow]就是不重复元素

Untitled

public 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[slow]=nums[fast];//把不重复的数字,赋值给slow的下一位
            }
            fast++;//如果快慢指针数字相同,快指针向下一位
        }
        return slow + 1;
    }

有序链表和数组去重一模一样,唯一的区别是把数组赋值操作变成操作指针

Untitled

public ListNode deleteDuplicates(ListNode head) {
        if(head==null)  return null;
        ListNode slow = head,fast = head;
        while(fast!=null){
            if(fast.val != slow.val){
                slow.next = fast;//链表上的指针
                slow = slow.next;//先赋值再移位置
            }
            fast = fast.next;
        }
        slow.next = null;
        return head;
    }

移动元素?

要求把 nums 中所有值为 val 的元素原地删除,依然使用双指针技巧的快慢指针。

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

public int removeElement(int[] nums, int val) {
        int fast =0 ,slow = 0;
        while(fast< nums.length){
            if(nums[fast]!=val){//不是指定值
                nums[slow] = nums[fast];//先赋值再++,保证nums[0...slow-1]是不包含val元素的,最后的结果数组长度就是slow
                slow++;
            }
            fast++;
        }
        return slow;
    }

移动零

将所有0移到最后,相当于移除nums中的所有0,然后再把后面的元素都赋值为0

public void moveZeroes(int[] nums) {
        int p = removeElement(nums,0);//去除nums中所有0,返回去除0之后的数组长度
        for(;p<nums.length;p++){
            nums[p] = 0;//将p之后的所有元素赋值为0
        }
    }
    int removeElement(int[] nums, int val) {
        int fast =0 ,slow = 0;
        while(fast< nums.length){
            if(nums[fast]!=val){//不是指定值
                nums[slow] = nums[fast];//先赋值再++,保证nums[0...slow-1]是不包含val元素的,最后的结果数组长度就是slow
                slow++;
            }
            fast++;
        }
        return slow;
    }
}

标签:slow,nums,int,fast,原地,修改,数组,指针
来源: https://www.cnblogs.com/autumnmoonming/p/16282439.html