天天看點

LeetCode178--撲克牌中的順子(O61)、圓圈中最後剩下的數字(O62)、股票的最大利潤(O63)、求1+2+3……+n(O64)、二叉樹的最近公共祖先(O68II)

1、撲克牌中的順子

//從撲克牌中随機抽5張牌,判斷是不是一個順子,即這5張牌是不是連續的。2~10為數字本身,A為1,J為11,Q為12,K為13,而大、小王為 0 ,可以看成任

//意數字。A 不能視為 14。

//

//

//

// 示例 1:

//

// 輸入: [1,2,3,4,5]

//輸出: True

//

//

//

// 示例 2:

//

// 輸入: [0,0,1,2,5]

//輸出: True

//

//

//

// 限制:

//

// 數組長度為 5

//

// 數組的數取值為 [0, 13] .

// Related Topics 數組 排序

public boolean isStraight(int[] nums) {
        Arrays.sort(nums);
        int count = 0;
        int num = 0;
        for (int i = 0; i < 5; i++) {
            if(nums[i] != 0){
                break;
            }
            count++;
        }
        for (int i = count; i < 4; i++) {
            if(nums[i+1] - nums[i] > 1){
                num += nums[i+1] - nums[i] - 1;
            }
            if(nums[i+1] == nums[i]){
                return false;
            }
        }
        if(num > count){
            return false;
        }
        return true;
    }
           

2、圓圈中最後剩下的數字

//0,1,···,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈裡删除第m個數字(删除後從下一個數字開始計數)。求出這個圓圈裡剩下的最後一個數字。

//

//

// 例如,0、1、2、3、4這5個數字組成一個圓圈,從數字0開始每次删除第3個數字,則删除的前4個數字依次是2、0、4、1,是以最後剩下的數字是3。

//

//

//

// 示例 1:

//

//

//輸入: n = 5, m = 3

//輸出: 3

//

//

// 示例 2:

//

//

//輸入: n = 10, m = 17

//輸出: 2

//

//

//

//

// 限制:

//

//

// 1 <= n <= 10^5

// 1 <= m <= 10^6

//

// Related Topics 遞歸 數學

這題可以采用模拟和數學兩種方式解決,

方法一:模拟法

模拟采用ArrayList,直接不停删除下一個,知道長度為1,下一個直接可以計算出來idx+m-1就是下一個要删除的值,至于減一是因為你删除了目前數之後後面的數往前移了。

public int lastRemaining(int n, int m) {
        /*List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < n; i++) {
            list.add(i);
        }
        int idx = 0;
        while(n > 1){
            idx = (idx + m - 1)%n;
            list.remove(idx);
            n--;
        }
        return list.get(0);
 }

           

方法二:數學法

https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/javajie-jue-yue-se-fu-huan-wen-ti-gao-su-ni-wei-sh/

3、股票的最大利潤

//假設把某股票的價格按照時間先後順序存儲在數組中,請問買賣該股票一次可能獲得的最大利潤是多少?

//

//

//

// 示例 1:

//

// 輸入: [7,1,5,3,6,4]

//輸出: 5

//解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。

// 注意利潤不能是 7-1 = 6, 因為賣出價格需要大于買入價格。

//

//

// 示例 2:

//

// 輸入: [7,6,4,3,1]

//輸出: 0

//解釋: 在這種情況下, 沒有交易完成, 是以最大利潤為 0。

//

//

//

// 限制:

//

// 0 <= 數組長度 <= 10^5

//

//

//

// 注意:本題與主站 121 題相同:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-s

//tock/

// Related Topics 數組 動态規劃

根本就沒必要用動态規劃,直接要找到目前值之前的最小值相減就行了。

public int maxProfit(int[] prices) {
        int minPrice = Integer.MAX_VALUE;
        int maxProfit = 0;
        for (int i = 0; i < prices.length; i++) {
            if(prices[i] < minPrice){
                minPrice = prices[i];
            }else if(prices[i] - minPrice > maxProfit){
                maxProfit = prices[i] - minPrice;
            }
        }
        return maxProfit;
    }
           

4、求1+2+3……+n

//求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。

//

//

//

// 示例 1:

//

// 輸入: n = 3

//輸出: 6

//

//

// 示例 2:

//

// 輸入: n = 9

//輸出: 45

//

//

//

//

// 限制:

//

//

// 1 <= n <= 10000

//

// Related Topics 位運算 遞歸 腦筋急轉彎

直接采用遞歸,但是不然用判斷,就需要采用&&短路了,即前面是false,後面就不會判斷了

class Solution {
    int res = 0;
    public int sumNums(int n) {
        //所謂的&&短路,隻要前面為false,後面就不會再判斷
        //如果n>1成立,則向下開啟下層遞歸sumNums(n-1)
        //如果不成立則不會開啟
        boolean x = n > 1 && sumNums(n-1)>0;
        res += n;
        return res;
    }
}
           

5、二叉樹的最近公共祖先

//給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。

//

// 百度百科中最近公共祖先的定義為:“對于有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度盡可能大(

//一個節點也可以是它自己的祖先)。”

//

// 例如,給定如下二叉樹: root = [3,5,1,6,2,0,8,null,null,7,4]

//

//

//

//

//

// 示例 1:

//

// 輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1

//輸出: 3

//解釋: 節點 5 和節點 1 的最近公共祖先是節點 3。

//

//

// 示例 2:

//

// 輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4

//輸出: 5

//解釋: 節點 5 和節點 4 的最近公共祖先是節點 5。因為根據定義最近公共祖先節點可以為節點本身。

//

//

//

//

// 說明:

//

//

// 所有節點的值都是唯一的。

// p、q 為不同節點且均存在于給定的二叉樹中。

//

//

// 注意:本題與主站 236 題相同:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a

//-binary-tree/

// Related Topics 樹 深度優先搜尋 二叉樹

這個其實之前就做過,就判斷條件比較多而已,現在看到樹的題目就有點煩,看來樹還是很欠火候啊

class Solution {
	TreeNode ans = null;
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		dfs(root, p, q);
		return ans;
	}
	//這個是判斷p,q中的某一個是否在以node為根節點的子樹上
    private boolean dfs(TreeNode node, TreeNode p, TreeNode q){
    	if(node == null)return false;
    	boolean lson = dfs(node.left, p, q);
    	boolean rson = dfs(node.right, p, q);
    	if((lson&&rson) || (node.val == p.val || node.val == q.val)&&(lson || rson)){
    		ans = node;
		}
    	return lson || rson || (node.val == p.val || node.val == q.val);
	}
}
           

繼續閱讀