LeetCode 965. 单值二叉树 / 467. 环绕字符串中唯一的子字符串 / 699. 掉落的方块(线段树后面再写)

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 965. 单值二叉树 / 467. 环绕字符串中唯一的子字符串 / 699. 掉落的方块(线段树后面再写)相关的知识,希望对你有一定的参考价值。

965. 单值二叉树

2022.5.24 每日一题

题目描述

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。

只有给定的树是单值二叉树时,才返回 true;否则返回 false。

示例 1:


输入:[1,1,1,1,1,null,1]
输出:true

示例 2:


输入:[2,2,2,5,2]
输出:false

提示:

给定树的节点数范围是 [1, 100]。
每个节点的值都是整数,范围为 [0, 99] 。

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

思路

/**
 * 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 boolean isUnivalTree(TreeNode root) 
        //直接遍历
        int val = root.val;
        return order(root, val);
    

    public boolean order(TreeNode root, int v)
        if(root == null)
            return true;
        boolean ll = order(root.left, v);
        if(!ll)
            return false;
        boolean rr = order(root.right, v);
        if(!rr)
            return false;
        if(root.val != v)
            return false;
        return true;
    

467. 环绕字符串中唯一的子字符串

2022.5.25 每日一题

题目描述

把字符串 s 看作是 “abcdefghijklmnopqrstuvwxyz” 的无限环绕字符串,所以 s 看起来是这样的:

“…zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd…” .
现在给定另一个字符串 p 。返回 s 中 唯一 的 p 的 非空子串 的数量 。

示例 1:

输入: p = “a”
输出: 1
解释: 字符串 s 中只有一个"a"子字符。

示例 2:

输入: p = “cac”
输出: 2
解释: 字符串 s 中的字符串“cac”只有两个子串“a”、“c”。.

示例 3:

输入: p = “zab”
输出: 6
解释: 在字符串 s 中有六个子串“z”、“a”、“b”、“za”、“ab”、“zab”。

提示:

1 <= p.length <= 10^5
p 由小写英文字母构成

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

思路

遍历26次,统计每个字母开头的子串最长长度,有点啰嗦,但是很明确

class Solution 
    public int findSubstringInWraproundString(String p) 
        //其实就是看p中有多少个连续出现的那种像s中排列的字符
        //但是不能统计重复的,想想这个该怎么办
        //直接统计以哪个字母打头的非空子串就可以吧
        //有26个字母,遍历26次,统计以每个字母开头的子串长度

        int l = p.length();
        int[] maxlen = new int[26];
        Arrays.fill(maxlen, -1);
        for(int k = 0; k < 26; k++)
            char c = (char)('a' + k);
            int len = -1;
            for(int i = 0; i < l;)
                if(p.charAt(i) == c)
                    len = 0;
                    i++;
                    maxlen[k] = Math.max(maxlen[k], len);
                    //如果还能继续延长
                    while(i < l && p.charAt(i) - 'a' == (p.charAt(i - 1) + 1 - 'a') % 26)
                        len++;
                        maxlen[k] = Math.max(maxlen[k], len);
                        i++;
                    
                    len = -1;
                else
                    i++;
                
            
        

        int res = 0;
        for(int k = 0; k < 26; k++)
            res += maxlen[k] + 1;
        
        return res;
    

定义为统计以某个字母结尾的子串长度更简洁

class Solution 
    public int findSubstringInWraproundString(String p) 
        //统计以某一个字符结尾的子串更方便

        int l = p.length();
        int[] maxlen = new int[26];
        int len = 1;
        for(int i = 0; i < l; i++)
            if(i > 0 && p.charAt(i) - 'a' == (p.charAt(i - 1) + 1 - 'a') % 26)
                len++;
            else
                len = 1;
            
            maxlen[p.charAt(i) - 'a'] = Math.max(maxlen[p.charAt(i) - 'a'], len);
        

        int res = 0;
        for(int k = 0; k < 26; k++)
            res += maxlen[k];
        
        return res;
    

699. 掉落的方块

2022.5.26 每日一题

题目描述

在二维平面上的 x 轴上,放置着一些方块。

给你一个二维整数数组 positions ,其中 positions[i] = [lefti, sideLengthi] 表示:第 i 个方块边长为 sideLengthi ,其左侧边与 x 轴上坐标点 lefti 对齐。

每个方块都从一个比目前所有的落地方块更高的高度掉落而下。方块沿 y 轴负方向下落,直到着陆到 另一个正方形的顶边 或者是 x 轴上 。一个方块仅仅是擦过另一个方块的左侧边或右侧边不算着陆。一旦着陆,它就会固定在原地,无法移动。

在每个方块掉落后,你必须记录目前所有已经落稳的 方块堆叠的最高高度 。

返回一个整数数组 ans ,其中 ans[i] 表示在第 i 块方块掉落后堆叠的最高高度。

示例 1:


输入:positions = [[1,2],[2,3],[6,1]]
输出:[2,5,5]
解释:
第 1 个方块掉落后,最高的堆叠由方块 1 组成,堆叠的最高高度为 2 。
第 2 个方块掉落后,最高的堆叠由方块 1 和 2 组成,堆叠的最高高度为 5 。
第 3 个方块掉落后,最高的堆叠仍然由方块 1 和 2 组成,堆叠的最高高度为 5 。
因此,返回 [2, 5, 5] 作为答案。

示例 2:

输入:positions = [[100,100],[200,100]]
输出:[100,100]
解释:
第 1 个方块掉落后,最高的堆叠由方块 1 组成,堆叠的最高高度为 100 。
第 2 个方块掉落后,最高的堆叠可以由方块 1 组成也可以由方块 2 组成,堆叠的最高高度为 100 。
因此,返回 [100, 100] 作为答案。
注意,方块 2 擦过方块 1 的右侧边,但不会算作在方块 1 上着陆。

注意:

1 <= positions.length <= 1000.
1 <= positions[i][0] <= 10^8.
1 <= positions[i][1] <= 10^6.

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

思路

写了个暴力解,主流解法还是线段树,最近没时间看了,先这样

class Solution 
    public List<Integer> fallingSquares(int[][] positions) 
        //就是一直往上垒,关键是找当前长度范围内,最高的点
        //也就是改变区间高度,查询区间最大值,然后改变区间,好像是线段树、树状数组之类的东西
        
        //因为方块数并不多,所以可以用暴力
        //记录每一个已经下落方块的高度,然后一直往上堆叠

        int l = positions.length;
        List<Integer> height = new ArrayList<>();
        List<Integer> max = new ArrayList<>();
        for(int i = 0; i < l; i++)
            int left = positions[i][0];
            int len = positions[i][1];
            int high = 0;
            //遍历之前所有方块
            for(int j = 0; j < i; j++)
                //如果掉下来的方块在这个方块上
                //怎么判断是否是在这个方块上面,就是左端点小于下面方块右端点的同时,右端点要大于下面方块左端点
                if(left + len - 1 >= positions[j][0] && left <= positions[j][0] + positions[j][1] - 1)
                    high = Math.max(high, height.get(j) + len);
                
            
            if(high == 0)
                high = len; 
            height.add(high);
            if(i == 0)
                max.add(high);
            else
                max.add(Math.max(max.get(i - 1), high));
        

        return max;
    

以上是关于LeetCode 965. 单值二叉树 / 467. 环绕字符串中唯一的子字符串 / 699. 掉落的方块(线段树后面再写)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode-965.单值二叉树

965. 单值二叉树

Leetcode-965 Univalued Binary Tree(单值二叉树)

LeetCode 965. Univalued Binary Tree

单值二叉树(2021-8-8)

c_cpp 965.单值二叉树