HOT 100(81~100)【LeetCode】1

简介: HOT 100(81~100)【LeetCode】1

HOT 100(81~100)

前言

2023-7-2 10:44:12

推荐

HOT 100(1~20)【LeetCode】

HOT 100(21~40)【LeetCode】

HOT 100(41~60)【LeetCode】

HOT 100(61~80)【LeetCode】

337. 打家劫舍 III【中等】

打家劫舍 III

中等

1.7K

相关企业

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。


给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。

示例 1:
输入: root = [3,2,3,null,3,null,1]
输出: 7 
解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7
示例 2:
输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9

提示:

树的节点数在 [1, 104] 范围内

0 <= Node.val <= 104

参考

/**
 * 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 {
    Map<TreeNode,Integer> f=new HashMap<>();//选择结点o
    Map<TreeNode,Integer> g=new HashMap<>();//不选择结点o
    public int rob(TreeNode root) {
        dfs(root);
        return Math.max(f.getOrDefault(root,0),g.getOrDefault(root,0));
    }
    public void dfs(TreeNode node){
        if(node==null){
            return;
        }
        dfs(node.left);
        dfs(node.right);
        //选择了o,就不能选择左 右孩子
        f.put(node,node.val+g.getOrDefault(node.left,0)+g.getOrDefault(node.right,0));
        //不选择o,可选择最大的(选择左||不选择左)+(选择右||不选择右)
        g.put(node,Math.max(f.getOrDefault(node.left,0),g.getOrDefault(node.left,0))
            +Math.max(f.getOrDefault(node.right,0),g.getOrDefault(node.right,0)));
    }
}

338. 比特位计数【简单】

338.比特位计数
简单

1.1K

相关企业

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

示例 1:
输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10
示例 2:
输入:n = 5
输出:[0,1,1,2,1,2]
解释:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101

提示:

0 <= n <= 105

进阶:

很容易就能实现时间复杂度为 O(n log n) 的解决方案,你可以在线性时间复杂度 O(n) 内用一趟扫描解决此问题吗?

你能不使用任何内置函数解决此问题吗?(如,C++ 中的 __builtin_popcount
调用函数

class Solution {
    public int[] countBits(int n) {
        int[] count=new int[n+1];
        for(int i=0;i<=n;i++){
            count[i]=Integer.bitCount(i);
        }
        return count;
    }
}

实现bitCount

class Solution {
    public int[] countBits(int n) {
        int[] count=new int[n+1];
        for(int i=0;i<=n;i++){
            count[i]=bitCount(i);
        }
        return count;
    }
    int bitCount(int i){
        int count=0;
        while(i!=0){
            if(i%2==1){
                count++;
            }
            i/=2;
        }
        return count;
    }
}
//Brian Kernighan 算法的原理是:对于任意整数 xxx,令 x=x & (x−1),该运算将 x 的二进制表示的最后一个 1 变成 0。因此,对 x 重复该操作,直到 x 变成 0,则操作次数即为 x 的「一比特数」
    public int countOnes(int x) {
        int ones = 0;
        while (x > 0) {
            x &= (x - 1);
            ones++;
        }
        return ones;
    }

347. 前 K 个高频元素【中等】

  1. 前 K 个高频元素
    中等
    1.6K
    相关企业
    给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]

提示:


1 <= nums.length <= 105

k 的取值范围是 [1, 数组中不相同的元素的个数]

题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的


进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。


Map排序

import java.util.Map.Entry;
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //统计
        HashMap<Integer,Integer> map=new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }
        Stream<Entry<Integer, Integer>> sorted = map.entrySet().stream().sorted(new Comparator<Entry<Integer, Integer>>() {
            @Override
            public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
                return o2.getValue() - o1.getValue();
            }
        });
//        sorted.forEach(t-> System.out.println(t.getKey()+" "+t.getValue()));
        int[] res=new int[k];
        int c=0;
        ArrayList<Integer> list=new ArrayList<>();
        sorted.limit(k).forEach(entry->list.add(entry.getKey()));
        for (Integer i : list) {
            res[c++]=i;
        }
        return res;
    }
}

参考

堆(优先队列)

import java.util.Map.Entry;
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //统计
        HashMap<Integer,Integer> map=new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }
        //int[] 的第一个元素代表数组的值,第二个元素代表了改值出现的次数
        PriorityQueue<int[]> queue=new PriorityQueue<int[]>(new Comparator<int[]>(){
            public int compare(int[] m,int[] n){
                return m[1]-n[1];
            }
        });
        for(Map.Entry<Integer,Integer> entry:map.entrySet()){
            int num=entry.getKey(),count=entry.getValue();
            //队列大小保持k个
            if(queue.size()==k){
                if(queue.peek()[1]<count){//小的话,逐出 添加当前
                    queue.poll();
                    queue.offer(new int[]{num,count});
                }
            }else{//不到k个,直接添加
                queue.offer(new int[]{num,count});
            }
        }
        int[] res=new int[k];
        for (int i=0;i<k;i++) {
            res[i]=queue.poll()[0];
        }
        return res;
    }
}

394. 字符串解码【中等】

字符串解码

中等

1.5K

相关企业

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。


你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。


此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

示例 1:
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

提示:

1 <= s.length <= 30

s 由小写英文字母、数字和方括号 ‘[]’ 组成

s 保证是一个 有效 的输入。

s 中所有整数的取值范围为 [1, 300]
参考

class Solution {
    int ptr;
    public String decodeString(String s) {
        LinkedList<String> stk=new LinkedList<>();
        ptr=0;
        while(ptr<s.length()){
            char cur=s.charAt(ptr);
            if(Character.isDigit(cur)){
                //获取一个数字并进栈
                String dights=getDights(s);
                stk.addLast(dights);
            }else if(Character.isLetter(cur)||cur=='['){
                //获取一个字母进栈
                stk.addLast(String.valueOf(s.charAt(ptr++)));
            }else{//有括号的情况
                ++ptr;
                LinkedList<String> sub=new LinkedList<String>();
                while(!"[".equals(stk.peekLast())){
                    sub.addLast(stk.removeLast());
                }
                //逆序
                Collections.reverse(sub);
                //左括号出栈
                stk.removeLast();
                //此时栈顶为当前sub对应的字符串应该出现的次数
                int repTime=Integer.parseInt(stk.removeLast());
                StringBuffer t=new StringBuffer();
                String o=getString(sub);
                //构造字符串
                while(repTime-->0){
                    t.append(o);
                }
                //将构造好的字符串入栈
                stk.addLast(t.toString());
            }
        }
        return getString(stk);
    }
    //数字编码可能不止1位
    public String getDights(String s){
        StringBuffer ret=new StringBuffer();
        while(Character.isDigit(s.charAt(ptr))){
            ret.append(s.charAt(ptr++));
        }
        return ret.toString();
    }
    //转换结果
    public String getString(LinkedList<String> v) {
        StringBuffer ret = new StringBuffer();
        for (String s : v) {
            ret.append(s);
        }
        return ret.toString();
    }
}

参考

递归

class Solution {
    String src;
    int ptr;
    public String decodeString(String s) {
        src=s;
        ptr=0;
        return getString();
    }
    public String getString(){
        if(ptr==src.length()||src.charAt(ptr)==']'){
            //String->EPS
            return "";
        }
        char cur=src.charAt(ptr);
        int repTime=1;
        String ret="";
        if(Character.isDigit(cur)){
            //String -> Digits [String] String
            //解析Digits
            repTime=getDights();
            //过滤左括号
            ++ptr;
            //解析String
            String str=getString();
            //过滤有括号
            ++ptr;
            //构造字符串
            while(repTime-->0){
                ret+=str;
            }
        }else if(Character.isLetter(cur)){
            //Sting -> Char String
            //解析Char
            ret=String.valueOf(src.charAt(ptr++));
        }
        return ret+getString();
    }
    //数字编码可能不止1位
    public int getDights(){
        int ret=0;
        while(ptr<src.length()&&Character.isDigit(src.charAt(ptr))){
            ret=ret*10+src.charAt(ptr++)-'0';
        }
        return ret;
    }
}
相关文章
|
1月前
|
存储 算法
《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数
《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数
|
1月前
|
网络协议
《 LeetCode 热题 HOT 100》——无重复字符的最长子串
《 LeetCode 热题 HOT 100》——无重复字符的最长子串
|
1月前
《LeetCode 热题 HOT 100》—— 两数相加
《LeetCode 热题 HOT 100》—— 两数相加
|
10月前
|
缓存 调度
HOT 100(导航)【LeetCode】
HOT 100(导航)【LeetCode】
56 0
|
10月前
|
调度
HOT 100(81~100)【LeetCode】4
HOT 100(81~100)【LeetCode】4
27 0
|
10月前
HOT 100(81~100)【LeetCode】3
HOT 100(81~100)【LeetCode】3
23 0
|
10月前
|
人工智能 BI 索引
HOT 100(81~100)【LeetCode】2
HOT 100(81~100)【LeetCode】2
39 0
|
10月前
|
缓存 Java 测试技术
HOT 100(41~60)【LeetCode】3
HOT 100(41~60)【LeetCode】3
29 0
|
10月前
|
存储 人工智能 算法
HOT 100(61~80)【LeetCode】1
HOT 100(61~80)【LeetCode】1
54 0
|
10月前
|
算法
HOT 100(21~40)【LeetCode】4
HOT 100(21~40)【LeetCode】4
26 0