上岸算法 I LeetCode Weekly Contest 223解題報告

No.1 解碼異或後的數組數組

解題思路函數

a ^ b = c 則有 a ^ b ^ a = c ^ ab = a ^ c優化

代碼展現ui

class Solution {
    public int[] decode(int[] encoded, int first) {
        int[] res = new int[encoded.length + 1];
        res[0] = first;
        for (int i = 0; i < encoded.length; i++) {
            // res[i] ^ res[i+1] = encoded[i]
            res[i + 1] = encoded[i] ^ res[i];
        }
        return res;
    }
}

No.2交換鏈表中的節點code

解題思路get

比較樸素的實現,封裝了一個函數,遍歷三次鏈表。it

代碼展現io

class Solution {
    public ListNode swapNodes(ListNode head, int k) {
        int n = 0;
        for (ListNode cur = head; cur != null; cur = cur.next) {
            n++;
        }
        ListNode a = getKthNode(head, k);
        ListNode b = getKthNode(head, n - k + 1);
        int tmp = a.val;
        a.val = b.val;
        b.val = tmp;
        return head;
    }

    ListNode getKthNode(ListNode head, int k) {
        ListNode cur = head;
        for (int i = 0; cur != null; i++, cur = cur.next) {
            if (i == k - 1) {
                return cur;
            }
        }
        return null;
    }
}

No.3執行交換操做後的最小漢明距離class

解題思路stream

使用並查集維護集合 —— 一個位置的數字與其餘哪些位置的數字可交換。

而後貪心法計數便可。

代碼展現

class UnionFind {
    public UnionFind(int size) {
        f = new int[size];
        Arrays.fill(f, -1);
    }

    public int find(int x) {
        if (f[x] < 0)
            return x;
        return f[x] = find(f[x]);
    }

    public boolean merge(int a, int b) {
        int fa = find(a);
        int fb = find(b);
        if (fa == fb)
            return false;
        f[fa] = fb;
        return true;
    }

    private int[] f;
}


class Solution {
    public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) {
        UnionFind uf = new UnionFind(source.length);
        for (int[] a : allowedSwaps) {
            uf.merge(a[0], a[1]);
        }
        // map[i] 是一個 counter
        // map[i][j] > 0 表示 source[i] 能夠經過交換變成 j
        // 使用 map<int,map> 而不是 map<int,set> 的緣由是避免 source 有重複數字
        Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
        for (int i = 0; i < source.length; i++) {
            int fi = uf.find(i);
            if (!map.containsKey(fi)) {
                map.put(fi, new HashMap<>());
            }
            Map<Integer, Integer> cnt = map.get(fi);
            cnt.put(source[i], cnt.getOrDefault(source[i], 0) + 1);
            map.put(i, cnt);
        }
        int res = target.length;
        for (int i = 0; i < target.length; i++) {
            Map<Integer, Integer> cnt = map.get(i);
            if (cnt.getOrDefault(target[i], 0) > 0) {
                res--;
                cnt.put(target[i], cnt.get(target[i]) - 1);
            }
        }
        return res;
    }
}

No.4完成全部工做的最短期

解題思路

二分 + 枚舉

代碼展現

class Solution {
    public int minimumTimeRequired(int[] jobs, int k) {
        // 使用 long 以免 (l + r) 溢出
        long l = Arrays.stream(jobs).min().getAsInt();
        long r = Arrays.stream(jobs).sum();
        while (l + 1 < r) {
            long mid = (l + r) / 2;
            if (check(jobs, k, mid)) {
                r = mid;
            } else {
                l = mid;
            }
        }
        return (int) (check(jobs, k, l) ? l : r);
    }

    boolean check(int[] jobs, int k, long limit) {
        // 判斷 k 個工人可否在 limit 的時限下完成任務
        return dfs(jobs, 0, new int[k], limit);
    }

    // 枚舉每一個任務分配給哪一個工人
    // sum[i] 表示當前 i 工人獲得的任務的總工時
    boolean dfs(int[] jobs, int curJob, int[] sum, long limit) {
        if (curJob == jobs.length) {
            return true;
        }
        for (int i = 0; i < sum.length; i++) {
            if (sum[i] + jobs[curJob] <= limit) {
                sum[i] += jobs[curJob];
                if (dfs(jobs, curJob + 1, sum, limit)) {
                    return true;
                }
                sum[i] -= jobs[curJob];
                // 一個很重要的優化
                // sum[i] = 0 表示 curJob 被分給一個新的工人
                // 若是未能在上方 return true, 換一個新工人也不可能達標
                if (sum[i] == 0) {
                    break;
                }
            }
        }
        return false;
    }
}
相關文章
相關標籤/搜索