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);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值