Leetcode contests 95 題解
阿新 • • 發佈:2018-11-27
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);
}
}