【从零开始刷leetcode-4】283. 移动零

题目

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

输入: nums = [0]
输出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

进阶:你能尽量减少完成的操作次数吗?

解法

解法一

  • pre指针向前推进,每遇到一个0,就将创建指针指向后面的数,让后面的元素都向前推,最后将长度-1;
  • 给数组末尾补零至原本的长度。
class Solution {
    public void moveZeroes(int[] nums) {
        if (nums.length == 1 && nums[0] == 0) return;
        int length = nums.length;
        int pre = 0;
        for(int cnt = 0 ; cnt < nums.length; cnt++) {
            if (nums[pre] == 0) {
                int tail = pre + 1;
                while (tail < nums.length) {
                    nums[tail-1] = nums[tail];
                    tail++;
                }
                pre--;
                length--;
            }
            pre++;
        }
        while (length < nums.length) {
            nums[length] = 0;
            length++;
        }
    }
}

时间复杂度:O(N2),不出意料速度很差

解法二 正经的双指针

i指针从头到尾遍历,每遇到非零元素,就赋值给j指针所在位置。

因为j指针只记录非零元素,所以j指针一定比i指针慢。不会有错误覆盖的情况。

class Solution {
    public void moveZeroes(int[] nums) {
        int j = 0;
        for(int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                nums[j++] = nums[i];
            }
        }
        while (j < nums.length) {
            nums[j++] = 0;
        }
    }
}

时间复杂度:O(N)

小结

双指针篇开始

问题在于没有意识到y指针实际上就是保存的非负元素,不需要每一次遇到0都将后面的元素前移。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇