LeetCode 1833. 雪糕的最大数量 / NC62 平衡二叉树 / NC7:股票(一次交易)/ NC22 合并两个有序的数组

1833. 雪糕的最大数量

2021.7.2每日一题

题目描述
夏日炎炎,小男孩 Tony 想买一些雪糕消消暑。

商店中新到 n 支雪糕,用长度为 n 的数组 costs 表示雪糕的定价,其中 costs[i] 表示第 i 支雪糕的现金价格。Tony 一共有 coins 现金可以用于消费,他想要买尽可能多的雪糕。

给你价格数组 costs 和现金量 coins ,请你计算并返回 Tony 用 coins 现金能够买到的雪糕的 最大数量 。

注意:Tony 可以按任意顺序购买雪糕。


示例 1:

输入:costs = [1,3,2,4,1], coins = 7
输出:4
解释:Tony 可以买下标为 0、1、2、4 的雪糕,总价为 1 + 3 + 2 + 1 = 7
示例 2:

输入:costs = [10,6,8,7,7,8], coins = 5
输出:0
解释:Tony 没有足够的钱买任何一支雪糕。
示例 3:

输入:costs = [1,6,3,1,2,5], coins = 20
输出:6
解释:Tony 可以买下所有的雪糕,总价为 1 + 6 + 3 + 1 + 2 + 5 = 18 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-ice-cream-bars
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

看到想到的就是贪心,排序,要是竞赛,就直接排序遍历了,看这个题号,应该也是之前一道竞赛题

class Solution {
    public int maxIceCream(int[] costs, int coins) {
        //直接排序,前面几个相加就行啊..
        //先看数据范围,不会超
        Arrays.sort(costs);
        int id = 0;
        while(id < costs.length){
            coins -= costs[id];
            if(coins < 0)
                break;
            id++;
        }
        return id;
    }
}

或者计数排序

class Solution {
    public int maxIceCream(int[] costs, int coins) {
        //动规怎么样,不会超时吧..
        int l = costs.length;
        int[] count = new int[100001];
        for(int i = 0; i < l; i++){
            count[costs[i]]++;
        }
        int res = 0;
        for(int i = 1; i <= 100000; i++){
            //当前能卖出的数量
            int sell = Math.min(coins / i, count[i]);
            coins -= i * sell;
            res += sell;
            if(coins < i){
                break;
            }

        }
        return res;
    }
}

动规,背包问题,超出内存限制

class Solution {
    public int maxIceCream(int[] costs, int coins) {
        //动规怎么样,不会超时吧..
        int l = costs.length;
        int[][] dp = new int[l + 1][coins + 1];

        for(int i = 1; i <= l; i++){
            for(int j = 1; j <= coins; j++){
                if(j < costs[i - 1])
                    dp[i][j] = dp[i - 1][j];
                else
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - costs[i - 1]] + 1);
            }
        }
        return dp[l][coins];
    }
}

改成一维的,超时了

class Solution {
    public int maxIceCream(int[] costs, int coins) {
        //动规怎么样,不会超时吧..
        int l = costs.length;
        int[] dp = new int[coins + 1];

        for(int i = 1; i <= l; i++){
            for(int j = coins; j >= costs[i - 1]; j--){
                dp[j] = Math.max(dp[j], dp[j - costs[i - 1]] + 1);
            }
        }
        return dp[coins];
    }
}

NC62 平衡二叉树

题目描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

注:我们约定空树是平衡二叉树。
示例1
输入:
{1,2,3,4,5,6,7}

返回值:
true
思路

自顶向下递归,从上到下依次计算每棵树的高度

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null)
            return true;
        int differ = Math.abs(helper(root.left) - helper(root.right));
        return differ <= 1 && IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
    
    public int helper(TreeNode node){
        if(node == null)
            return 0;
        return Math.max(helper(node.left), helper(node.right)) + 1;
    }
}

自底向上,减少了不必要的遍历

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null)
            return true;
        return helper(root) != -1;
    }
    
    public int helper(TreeNode node){
        if(node == null)
            return 0;
        int l = helper(node.left);
        if(l == -1)
            return -1;
        int r = helper(node.right);
        if(r == -1)
            return -1;
        int height = Math.max(l, r) + 1;
        //如果小于等于1,就返回高度,否则,返回-1,即不是平衡二叉树
        return Math.abs(l - r) <= 1 ? height : -1;
    }
}

NC7:股票(一次交易)

题目描述
假设你有一个数组,其中第 i 个元素是股票在第 i 天的价格。
你有一次买入和卖出的机会。(只有买入了股票以后才能卖出)。请你设计一个算法来计算可以获得的最大收益。
示例1
输入:
[1,4,2]

返回值:
3

示例2
输入:
[2,4,1]

返回值:
2
思路

简单的动规

import java.util.*;


public class Solution {
    /**
     * 
     * @param prices int整型一维数组 
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // write code here
        //又来做股票了
        //贪心
        int res = 0;
        int l = prices.length;
        if(l == 0)
            return 0;
        int min = prices[0];
        for(int i = 1; i < l; i++){
            min = Math.min(prices[i], min);
            res = Math.max(res, prices[i] - min);
        }
        return res;
    }
}

NC22 合并两个有序的数组

题目描述
给出一个整数数组 和有序的整数数组 ,请将数组 合并到数组 中,变成一个有序的升序数组
注意:
1.可以假设 数组有足够的空间存放 数组的元素, 和 中初始的元素数目分别为 和 ,的数组空间大小为 + 
2.不要返回合并的数组,返回是空的,将数组 的数据合并到里面就好了
3.数组在[0,m-1]的范围也是有序的

例1:
A: [1,2,3,0,0,0],m=3
B: [2,5,6],n=3
合并过后A为:
A: [1,2,2,3,5,6]
思路

从后向前合并就好了

public class Solution {
    public void merge(int A[], int m, int B[], int n) {
        int index = m + n - 1;
        int id1 = m - 1;
        int id2 = n - 1;
        while(id1 >= 0 && id2 >= 0){
            if(A[id1] < B[id2]){
                A[index--] = B[id2];
                id2--;
            }else{
                A[index--] = A[id1];
                id1--;
            }
        }
        while(id1 >= 0){
            A[index--] = A[id1--];
        }
        while(id2 >= 0){
            A[index--] = B[id2--];
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值