【數組】C081_LC_複寫零(暴力 / 優化 / 倒序遍歷)

一、Problem

Given a fixed length array arr of integers, duplicate each occurrence of zero, shifting the remaining elements to the right.

Note that elements beyond the length of the original array are not written.

Do the above modifications to the input array in place, do not return anything from your function.

Input: [1,0,2,3,0,4,5,0]
Output: null
Explanation: After calling your function, the input array is modified to: [1,0,0,2,3,0,0,4]

Note:

1 <= arr.length <= 10000
0 <= arr[i] <= 9

二、Solution

方法一:暴力插入

class Solution {
    public void duplicateZeros(int[] a) {
        int n = a.length;
        List<Integer> nums = new ArrayList<>(2);
        for (int i : a) nums.add(i);
        
        for (int i = 0; i < n; ) {
            if (nums.get(i) == 0) {
                nums.add(i+1, 0);
                i+=2;
            } else {
                i++;
            }
        }
        for (int i = 0; i < n; i++)
            a[i] = nums.get(i);
    }
}

優化思路

ArrayList 的插入是 O(n) 的,但我們並不需要真的將原數組拷貝經 List 中,然後在進行插入,取而代之的是:

遇到 0 就將 0 放到一個隊列 q 中,當隊列 q 不空時,證明有 0 需要被複寫,但此時的 0 後面的元素我們不能讓它丟失,所以我們也將其保存到隊列 q 中

class Solution {
    public void duplicateZeros(int[] a) {
        Queue<Integer> q = new LinkedList<>();
        for (int i = 0; i < a.length; i++) {
            if (a[i] == 0) 
                q.add(0);
            if (!q.isEmpty()) {
                q.add(a[i]);
                a[i] = q.poll();
            }
        }
    }
}
複雜度分析
  • 時間複雜度:O(n2)>O(n)O(n^2) ->O(n)
  • 空間複雜度:O(n)O(n)

方法二:倒序遍歷

思路

如果某一個非零元素的前面有 k 個 0,那麼這個非零元素的後面 k 個位置都會被替換,基於這一點,我們可以先統計 0 的個數,然後反向遍歷:

  • 遇到非 0 元素 a[i] 時,說明 a[i] 是要被移動 k 個位置的
  • 遇到 0 元素 a[i] 時,也說明 a[i] 是要被移動 k 個位置的,但移動的時候我們還要將 0 進行復制,所以 0 後面 k、k+1 這兩個位置是要被改爲 0 的
class Solution {
    public void duplicateZeros(int[] a) {
        int k = 0, n = a.length;
        for (int i : a) if (i == 0)
            k++;

        for (int i = n-1; i >= 0; i--) {
            if (a[i] == 0) {
                k--;
                if (i + k < n)      a[i+k] = 0;
                if (i + k + 1 < n)  a[i+k+1] = 0;
            } else if (i + k < n) {
                a[i+k] = a[i];
            }
        }
    }
}
複雜度分析
  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章