《劍指 offer》專題第七部。
題目:劍指 offer 66. 構建乘積陣列。
定義:\[\begin
v_1[i] = \prod_^ a[k] = a[0] \times a[1] \times \dots \times a[i-1], \quad&v_1[0] = 1 \\
v_2[i] = \prod_^ a[k] = a[i+1] \times \dots \times a[n-1], \quad&v_2[n-1] = 1
\end
\]那麼有:
\[b[i] = v_1[i] \times v_2[i], 0 \le i \le n-1
\]**實現:
題目:劍指 offer 67. 把字串轉換成整數。class solution
};
思路很清晰,請看注釋。
題目:劍指 offer 68 - i. 二叉搜尋樹的最近公共祖先。class solution ;
auto issign = (char c) ;
int len = str.length(), i = 0;
// 忽律空格
while (i < len && str[i] == ' ') i++;
// 第乙個非空字元,如果不是 那麼返回 0
if (i == len || (!issign(str[i]) && !isdigit(str[i]))) return 0;
// 第乙個非空字元是否代表負數
bool neg = false;
if (issign(str[i])) neg = (str[i] == '-'), i++;
// 求出數字部分的絕對值
uint64_t val = 0;
while (i < len && isdigit(str[i]))
return neg ? -val: val; }};
p
和q
要麼都在左子樹,要麼都在右子樹。如果不是,說明當前的子樹的root
就是最近公共祖先。
題目:劍指 offer 68 - ii. 二叉樹的最近公共祖先。class solution
return r;}};
遞迴。基於後序遍歷,lca(r, p, q)
表示是否在子樹r
中找到p, q
中的任意乙個節點。
以下圖為例:
當輸入p=7, q=4
時,後序遍歷到 7 或 4 時,返回left = 7, right = 4
給 2 ,這時候 2 就會把自己返回給 5 .
在遍歷 5 的遞迴層中,left = nullptr, right = 2
,把right = 2
返回給 3 。
同理,在遍歷 3 的第一層遞迴中,left = 2, right = nullptr
,那麼就會把left = 2
返回給lowestcommonancestor
.
題目:面試題60. n個骰子的點數。class solution
treenode *lca(treenode *r, treenode *p, treenode *q)
};
動態規劃。
設 \(p(k)\) 是骰子點數和為 \(k\) 的概率,那麼 \(p(k)\) 等於 \(k\) 出現的次數除以總事件數目。
狀態定義:\(dp[i][j]\) 表示有 \(i\) 個骰子時,點數和為 \(j\) 的事件數。顯然有,\(i \le j \le 6i\) .
轉移方程:
\[dp[i][j] = \sum_^ dp[i-1][j-k], \quad if \quad (i-1) \le (j-k) \le 6(i-1)
\]解析:\(dp[i][j]\) 表示需要用 \(i\) 個骰子,擲出點數 \(j\) 。 考慮第 \(i\) 個骰子的點數可以是 \([1, 6]\) 的任意一種,因此 \(dp[i][j] = dp[i-1][j-1] + \dots + dp[i-1][j-6]\) .
邊界條件:\(dp[1][1, \dots, 6] = 1\) .
雖然二維陣列dp
是n x 6n
的,但是實際上並不是每個元素都有效,這是由狀態方程的定義決定的。前 3 行有效的元素的下標如下:
求出i=1 [1, 2, 3, 4, 5, 6]
i=2 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
i=3 [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
dp[n][n, ..., 6*n]
後,事件總數就是sum(dp[n][n, ..., 6*n])
.
空間優化:class solution ;
int rows = n, cols = 6*n;
vector> dp(rows+1, vector(cols+1, 0));
for (int j=1;j<=6;j++) dp[1][j] = 1;
for (int i=2;i<=rows;i++)
}vectorres;
int total = 0;
for (int i=n; i<=cols; i++) total+=dp[n][i];
for (int i=n; i<=cols; i++)
return res;}};
class solution
}vectorres;
int total = 0;
for (int i=n; i<=cols; i++) total+=dp[i];
for (int i=n; i<=cols; i++) res.push_back(((double)dp[i]) / total);
return res;}};
leetcode劍指offer 字串
二叉樹,鍊錶,字串 思路 進行兩次反轉 1.對整個句子反轉 2.對句子中的單詞反轉 經過三次反 1.反轉前面的字串。2.反轉後面的字串。3.反轉整個字串 不能直接用力扣46全排列的 力扣46是無重複的數字,這個題是有重複的。正確的解法 不用not in tmp來判斷這個字母是否需要遍歷,定義乙個us...
Leetcode劍指offer系列 平衡二叉樹
傳送門 輸入一棵二叉樹的根節點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意節點的左右子樹的深度相差不超過1,那麼它就是一棵平衡二叉樹。示例 1 給定二叉樹 3,9,20,null,null,15,7 3 9 20 15 7 返回 true 示例 2 給定二叉樹 1,2,2,3,3,null,nul...
LeetCode 劍指offer刷題10 1
leetcode 劍指offer刷題 劍指 offer 10 i.斐波那契數列 寫乙個函式,輸入 n 求斐波那契 fibonacci 數列的第 n 項。斐波那契數列的定義如下 f 0 0,f 1 1 f n f n 1 f n 2 其中 n 1.斐波那契數列由 0 和 1 開始,之後的斐波那契數就是...