283. Move Zeros

FB 的超高频

这种写法中,我们调用 swap 的次数取决于从数组第一个 0 开始,后面到底有多少个非 0 元素。

一次 swap = 2次数组写入 + 1次 temp variable 写入,总写入次数为 O(3n),总数组写入次数为 O(2n)

public class Solution {
    public void moveZeroes(int[] nums) {
        if (nums == null || nums.length == 0) return;

        int i = 0;
        while (i < nums.length && nums[i] != 0) i++;
        for (int j = i + 1; j < nums.length; ++j) {
            if (nums[j] != 0) swap(nums, i++, j);
        }
    }
    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

然后 follow-up 肯定是如何减少写入次数 (aka 别用 swap)

这个时候解法就有点像27了,不为目标值的时候(这道题目标值为0),我们把当前值覆盖到前面,从头开始覆盖,不用管被覆盖的值是多少,因为我们只关心最后的结果。

和27不太一样的是,最后要再把0写回去,当然操作是很trivial的。

其实我觉得这个写法才是最直观的,暴力点用 swap 的写法反而 tricky 一点

这种写法中,数组每一个位置一定会被不多不少写入一次,写入次数为 O(n)

public class Solution {
    public void moveZeroes(int[] nums) {
        if (nums == null || nums.length == 0) return;

        int ptr = 0;
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] != 0) nums[ptr++] = nums[i];
        }
        for (; ptr < nums.length; ++ptr) nums[ptr] = 0;
    }
}

287. Find the Duplicate Number

public class Solution {
    public int findDuplicate(int[] nums) {
        if (nums.length > 1) {
            int slow = nums[0];
            int fast = nums[nums[0]];

            while (fast != slow) {
                slow = nums[slow];
                fast = nums[nums[fast]];
            }
            fast = 0;
            while (fast != slow) {
                fast = nums[fast];
                slow = nums[slow];
            }
            return slow;
        }
        return -1;
    }
}

41. First Missing Positive

Pocket Gems 电面题库

这题真的垃圾,到现在也是记的答案。

思路就是不断试图把当前元素替换到其正确的位置上;如果目标位置元素已经正确则 do nothing,如果目标位置越界,也 do nothing. 每次交换之后指针位置不动,继续试图新一轮替换。这样一次循环之后,所有能被放到正确位置的元素,都会被放过去,而第一个位置和值不匹配的元素就是我们要寻找的目标。

注意要点:

  • 当前元素的目标位置 index 有可能越上下界,多加两个判断条件;

  • 如果真是 swap 了,不代表当前元素一定是正确位置,指针不要动(或者说在 for loop 里面要 i--)

public class Solution {
    public int firstMissingPositive(int[] nums) {
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] != i + 1 && nums[i] - 1 >= 0 &&
               nums[i] - 1 < nums.length && nums[nums[i] - 1] != nums[i]) {
                swap(nums, i, nums[i] - 1);
                i--;
            }
        }
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] != i + 1) return i + 1;
        }
        return nums.length + 1;
    }
    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

results matching ""

    No results matching ""