1. 程式人生 > >Leetcode contests 95 題解

Leetcode contests 95 題解

876. Middle of the Linked List

  簡單題,我的做法是先數下個數,然後知道中間節點是第幾個了。

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode p = head;
        int cnt = 0;
        while (p != null) {
            cnt++;
            p = p.next;
        }
        cnt /=2;
        p = head;
        while
(cnt>0) { p = p.next; cnt--; } return p; } }

877. Stone Game

  這道題我用了記憶化搜尋,用遞迴暴搜可能是能獲取到正確結果的,但是直接的遞迴在重複計算好東西,所以我用dp陣列把計算出來的結果儲存起來,用的時候直接調取結果,可以減少遞迴樹中重複的部分。
  dp[i][j][0] 表示[i,j]區間Alice能取到的最優結果,dp[i][j][1]表示[i,j]區間Lee能取到最優的結果。

class Solution {
    int
[][][] dp; public boolean stoneGame(int[] piles) { dp = new int[piles.length][piles.length][2]; int len = piles.length; int sum = 0; for (int i = 0; i < len; i++) { dp[i][i][0] = piles[i]; dp[i][i][1] = piles[i]; sum += piles[i]; } return
help(0, len-1, 0, piles)> sum/2; } private int help(int i, int j, int pos, int[] piles) { if (dp[i][j][pos] != 0) { return dp[i][j][pos]; } int newpos = pos^1; dp[i][j][newpos] = Math.max(help(i+1, j, newpos, piles), help(i, j-1, newpos, piles)); dp[i][j][pos] = Math.max(help(i+1, j, newpos, piles)+piles[i+1], help(i, j-1, newpos, piles)+piles[j-1]); return dp[i][j][pos]; } }

878. Nth Magical Number

   用容斥原理可以計算出一個數字Num之下有多少個A或B的倍數cnt,我們從最大值二分這個數字Num,拿cnt和N做比較來決定二分的走向,最終l和r肯定會收斂到一起,這就是我們要的結果了。
   這道題的數值範圍不是特別大 ,用long就可以完全滿足需求了。

class Solution {
    private long gcd(long x, long y) {
        if (x%y == 0)
            return y;
        return gcd(y, x%y);
    }
    public int nthMagicalNumber(int N, int A, int B) {
        long C = 1l*A*B/gcd(A, B);
        long r = 1000000000l*40000*40000;
        long l = 0;
        while(l < r) {
            long mid = (l+r)/2;
            long cnt = mid/A + mid/B - mid/C;
            if (cnt < N)
                l = mid+1;
            else
                r = mid;
        }
        return (int) (l%1000000007);
    }
}