今天算是個里程碑了
第一題 股票的最大利潤
使用貪心策略,假設第 i 輪進行賣出操作,買入操作價格應該是 i 之前并且價格最低
public class maxProfit {
public static int max(int[] arr) {
if(arr.length==0) return 0;
int maxprofit=0;
int min = arr[0];
//循環從1開始,因為要使用最低的買入策略arr[0]
for(int i=1;i<arr.length;i++) {
//找到i-1次前的最小買入點,與當前的買入點
min = Math.min(min, arr[i]);
//找到i-1次前的最大買入,與當前的買入的比較
maxprofit=Math.max(maxprofit, arr[i]-min);
}
return maxprofit;
}
public static void main(String[] args) {
int[] arr={3,2,5,7,9,1,0,3,5,12,7};
max(arr);
System.out.println(max(arr));
}
}
第二題 求 1+2+3+...+n
條件與 && 具有短路原則,即在第一個條件語句為 false 的情況下不會去執行第二個條件語句。利用這一特性,將遞歸的返回條件取非然后作為 && 的第一個條件語句,遞歸的主體轉換為第二個條件語句,那么當遞歸的返回條件為 true 的情況下就不會執行遞歸的主體部分,遞歸返回。
以下實現中,遞歸的返回條件為 n <= 0,取非后就是 n > 0,遞歸的主體部分為 sum += Sum_Solution(n - 1),轉換為條件語句后就是 (sum += Sum_Solution(n - 1)) > 0。
public static int sumf(int n) {
int sum=n;
boolean b = (n>0) && ((sum+=sumf(n-1))>0);
return sum;
}
第三題 不用加減乘除做加法
a ^ b 表示沒有考慮進位的情況下兩數的和,(a & b) << 1 就是進位。
遞歸會終止的原因是 (a & b) << 1 最右邊會多一個 0,那么繼續遞歸,進位最右邊的 0 會慢慢增多,最后進位會變為 0,遞歸終止。
第四題 構建乘積數組
給定一個數組 A[0, 1,..., n-1], 請構建一個數組 B[0, 1,..., n-1], 其中 B 中的元素 B[i]=A[0]A[1]...A[i-1]A[i+1]...A[n-1]。不能使用除法。
第五題 把字符串轉換成整數
第六題 樹中兩個節點的最低公共祖先
二叉查找樹中,兩個節點 p, q 的公共祖先 root 滿足 p.val <= root.val && root.val <= q.val,只要找到滿足這個條件的最低層節點即可。換句話說,應該先考慮子樹的解而不是根節點的解,二叉樹的后序遍歷操作滿足這個特性。在本題中我們可以利用后序遍歷的特性,先在左右子樹中查找解,最后再考慮根節點的解。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null)
return root;
if (root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left, p, q);
if (root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right, p, q);
return root;
}
在左右子樹中查找兩個節點的最低公共祖先,如果在其中一顆子樹中查找到,那么就返回這個解,否則可以認為根節點就是最低公共祖先。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q)
return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
}