leetcode hot/96-100

本文探讨了四个信息技术问题:寻找最短无序连续子数组、合并两个已排序二叉树、优化任务调度以满足冷却时间限制,以及计算字符串中回文子串的数量。通过实例解析和高效算法,揭示了这些技术应用场景和解题策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

581 - 最短无序连续子数组

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

请你找出符合题意的 最短 子数组,并输出它的长度。

示例 1:

输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9]进行升序排序,那么整个表都会变为升序排序。
示例 2:

输入:nums = [1,2,3,4]
输出:0
输入:nums = [1]
输出:0

class Solution {
    //从右到左:如果当前值的后面还有更小的值,不满足升序,当前值应该被排序
    //从左到右:如果当前值的前面还有更大的值,不满足升序,当前值应该被排序
    public int findUnsortedSubarray(int[] nums) {
        if(nums.length<=1 || nums==null) return 0;
        int len = nums.length;
        int min = nums[len-1], l=len-1;
        for(int i=len-2;i>=0;i--){
            if(nums[i]>min){
                l = i;
            }
            min = Math.min(nums[i],min);
        }
        int max = nums[0],r=0;
        for(int i= 1;i<len;i++){
            if(nums[i]<max){
                r = i;
            }
            max = Math.max(nums[i],max);
        }
        return Math.max(r-l+1,0);
    }
}

617-合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1== null) return root2;
        if(root2 == null) return root1;
        TreeNode node = new  TreeNode(root1.val+root2.val);
        node.left = mergeTrees(root1.left,root2.left);
        node.right = mergeTrees(root1.right,root2.right);
        return node;
    }
}

621-任务调度器

给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。

然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。

你需要计算完成所有任务所需要的 最短时间 。

示例 1:

输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
示例 2:

输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 0
输出:6
解释:在这种情况下,任何大小为 6的排列都可以满足要求,因为 n = 0 [“A”,“A”,“A”,“B”,“B”,“B”] [“A”,“B”,“A”,“B”,“A”,“B”] [“B”,“B”,“B”,“A”,“A”,“A”]
… 诸如此类
示例 3:
输入:tasks = [“A”,“A”,“A”,“A”,“A”,“A”,“B”,“C”,“D”,“E”,“F”,“G”], n = 2
输出:16
解释:一种可能的解决方案是:
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A

class Solution {
    //解题思路::https://leetcode-cn.com/problems/task-scheduler/solution/jian-ming-yi-dong-de-javajie-da-by-lan-s-jfl9/
    public int leastInterval(char[] tasks, int n) {
        int[] buckets = new int[26];
        for(int i=0;i<tasks.length;i++){
            buckets[tasks[i]-'A']++;
        }
        Arrays.sort(buckets);
        //maxTimes为出现次数最多的那个任务出现的次数
        int maxTimes = buckets[25];
        //maxCount为一共有多少个任务和出现最多的那个任务出现次数一样
        //初始化maxCount(最小为1,如果是0,则结果等于len)
        //如[A A B B C D] n = 2  1*3+2=5<6-->应该等于6
        int maxCount = 1;
        for(int i=25;i>=1;i--){
            //查找和最多任务数出现次数相同的
            if(buckets[i]==buckets[i-1]){
                maxCount++;
            }else{
                break;
            }
        }
        int res = (maxTimes-1)*(n+1)+maxCount;
        return Math.max(res,tasks.length);
    }
}

647-回文子串的长度

给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:“abc” 输出:3
解释:三个回文子串: “a”, “b”, “c”
示例 2:

输入:“aaa” 输出:6
解释:6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”

class Solution {
    //中心扩展
    public int countSubstrings(String s) {
        int n = s.length();
        char[] letters = s.toCharArray();
        //加上自己本身
        int ans = n;
        for(int k = 0;k<n;k++){
            //以letter[k]为中心向两边扩
            //注意以下用的是i--,是先判断的i 和 j
            //如果让 i = k,j = k,应该初始化ans=0
            int i= k-1,j=k+1;
            while(i>=0&&j<n&&letters[i--]==letters[j++]){
                ans++;
            }
            //以letters[k]以及右侧值为中心扩散
            i = k;
            j=k+1;
            while(i >= 0 && j < n && letters[i--] == letters[j++]){
                ans++;
            }
        }
        return ans;
    }
}

739-每日温度

请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是
[1, 1, 4, 2, 1, 1, 0, 0]。

提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

link

class Solution {
    //判别是否需要使用单调栈,如果需要找到左边或者右边第一个比当前位置的数大或者小,则可以考虑使用单调栈;
    //单调栈的题目如矩形面积等等
    public int[] dailyTemperatures(int[] temperatures) {
        int length  = temperatures.length;
        int[] ans = new int[length];
        Deque<Integer> stack = new LinkedList<>();
        for(int i=0;i<length;i++){
            int temperature = temperatures[i];
            while(!stack.isEmpty()&&temperature>temperatures[stack.peek()]){
                //者栈顶元素出栈,temperature即是靠近它的第一个比他大的元素
                int prevIndex = stack.pop();
                //记录栈顶元素对应下标的下一个增大温度的间隔
                ans[prevIndex] = i-prevIndex;
            }
            stack.push(i);
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值