• leetcode刷题 495~


    题目495题

    提莫攻击

    在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。

    你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。

    示例1:

    输入: [1,4], 2
    输出: 4
    原因: 第 1 秒初,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持 2 秒钟,直到第 2 秒末结束。
    第 4 秒初,提莫再次攻击艾希,使得艾希获得另外 2 秒中毒时间。
    所以最终输出 4 秒。

    思路

    双指针

    实现

    class Solution {
        public int findPoisonedDuration(int[] timeSeries, int duration) {
            int result = 0;
            int left = 0;
            int right = 0;
            for (int time: timeSeries){
                if (time >= right){
                    result += duration;
                    left = time;
                    right = left + duration;
                }
                else{
                    left = time;
                    result = result + duration + left  - right;
                    right = left + duration;
                }
            }
            return result;
        }
    }

    题目496题

    下一个更大的元素I

    给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

    nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。

    示例 1:

    输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
    输出: [-1,3,-1]

    思路

    单调栈:首先遍历nums2,利用哈希表记录每个元素下一个更大值。然后遍历nums1获取结果

    实现

    class Solution {
        public int[] nextGreaterElement(int[] nums1, int[] nums2) {
            Stack < Integer > stack = new Stack<>();
            HashMap < Integer, Integer > map = new HashMap < > ();
            for(int num: nums2){
                while(! stack.empty() && stack.peek()<num){
                    map.put(stack.pop(), num);
                }
                stack.push(num);
            }
            while(!stack.empty()){
                map.put(stack.pop(),-1);
            }
            int[] result = new int[nums1.length];
            for(int i = 0; i < nums1.length; i++){
                result[i] = map.get(nums1[i]);
            }
            return result;
        }
    }

    题目497题

    非重叠矩阵中的随机点

    给定一个非重叠轴对齐矩形的列表 rects,写一个函数 pick 随机均匀地选取矩形覆盖的空间中的整数点。

    示例 1:

    输入:
    ["Solution","pick","pick","pick"]
    [[[[1,1,5,5]]],[],[],[]]
    输出:
    [null,[4,1],[4,1],[3,3]]

    思路

    首先计算所有整数点的总和,然后采用蓄水池抽样,或者二分查找,找到随机点。

    实现

    import java.util.Random;
    class Solution {
        
        private int[][] rects;
        private int rectsNum = 0;
        private List<Integer> rectArray = new ArrayList<>();
        public Solution(int[][] rects) {
            this.rects = rects;
            for (int[] rect: rects){
                rectsNum += (rect[2] - rect[0] + 1)*(rect[3] - rect[1] + 1);
                rectArray.add(rectsNum);
            }
        }
    
        public int[] pick() {
            Random random =new Random();
            int randomIndex = random.nextInt(rectsNum);
            int left = 0;
            int right = rects.length-1;
            while(left != right){
                int mid = left + (right-left)/2;
                if(randomIndex >= rectArray.get(mid)){
                    left = mid +1;
                }
                else{
                    right = mid;
                }
            }
            int rectsIndex = left;
            int[] rect = rects[rectsIndex];
            int length = rect[2] - rect[0] + 1;
            int high = rect[3] - rect[1] + 1;
            int lengthIndex = random.nextInt(length);
            int highIndex = random.nextInt(high);
            int[] result = new int[2];
            result[0] = rect[0] + lengthIndex;
            result[1] = rect[1] + highIndex;
            return result;
        }
    }
    
    /**
     * Your Solution object will be instantiated and called as such:
     * Solution obj = new Solution(rects);
     * int[] param_1 = obj.pick();
     */

    题目498题

    对角线遍历

    给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

    思路实现

    class Solution {
        public int[] findDiagonalOrder(int[][] matrix) {
            if (matrix == null || matrix.length == 0) {
                return new int[]{};
            }
            int M = matrix.length, N = matrix[0].length;
            int[] result = new int[M*N];
            int row = 0, col = 0;
            for(int index = 0; index < M*N; index++){
                result[index] = matrix[row][col];
                int level = row+col;
                if(level%2==0){
                    if(col == N-1){
                        row += 1;
                    }
                    else if(row == 0){
                        col += 1;
                    }
                    else{
                        row -= 1;
                        col += 1;
                    }
                }
                else{
                    if(row == M-1){
                        col += 1;
                    }
                    else if(col == 0){
                        row += 1;
                    }
                    else{
                        col -= 1;
                        row += 1;
                    }
                }
            }
            return result;
        }
    }

    题目500题

    键盘行

    给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如下图所示。

    思路实现

    class Solution {
        public String[] findWords(String[] words) {
            String[] keyboard = new String[]{"QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM"};
            HashMap<Character,Integer> lines = new HashMap<>();
            for(int index = 0; index <3; index++){
                for(char c:keyboard[index].toCharArray()){
                    c = Character.toUpperCase(c);
                    lines.put(c,index);
                }
            }
            String[] result = new String[words.length];
            int count = 0;
            for(String word: words){
                Integer line = -1;
                boolean temp = true;
                for(char c:word.toCharArray()){
                    c = Character.toUpperCase(c);
                    Integer next = lines.get(c);
                    if (line != -1 && next != line){
                        temp = false;
                        break;
                    }
                    line = next;
                }
                if(temp == true){
                    result[count] = word;
                    count += 1;
                }
            }
            return Arrays.copyOf(result, count);
        }
    }

    题目501题

    二叉搜索树中的重数

    给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

    思路

    中序遍历

    实现

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        private List<Integer> answer = new ArrayList<Integer>();
        private int cur = 0, count = 0, MaxCount = 0;
        public int[] findMode(TreeNode root) {
            dfs(root);
            int[] result = answer.stream().mapToInt(k->k).toArray();
            return result;
        }
        
        private void dfs(TreeNode node){
            if (node == null){
                return;
            }
            dfs(node.left);
            check(node.val);
            dfs(node.right);
        }
    
        private void check(int val){
            if (val == cur){
                count += 1;
            }
            else{
                count = 1;
                cur = val;
            }
            if(count == MaxCount){
                answer.add(val);
            }
            else if (count > MaxCount){
                MaxCount = count;
                answer.clear();
                answer.add(val);
            }
        }
    }

    题目503题

    下一个更大元素II

    给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。

    示例 1:

    输入: [1,2,1]
    输出: [2,-1,2]
    解释: 第一个 1 的下一个更大的数是 2;
    数字 2 找不到下一个更大的数;
    第二个 1 的下一个最大的数需要循环搜索,结果也是 2。

    思路

    与496题相同思路相同,使用栈来解决问题。

    首先第一次遍历,得到部分下一个元素更大的结果,此时,栈中保存着一个单调递减的元素索引,其实第一个元素是整个数组的最大元素。遍历0到最大索引,将得到栈中值的结果。

    实现

    class Solution 
    {
        public int[] nextGreaterElements(int[] nums) 
        {
            if(nums.length == 0)
            {
                return new int[]{};
            }
            Stack < Integer > stack = new Stack<>();
            int[] result = new int[nums.length];
            for (int index=0; index<nums.length; index++)
            {
                while(!stack.empty() && nums[stack.peek()] < nums[index])
                {
                    int tempIndex = stack.pop();
                    result[tempIndex] = nums[index];
                }
                stack.push(index);
            }
            int maxIndex = stack.get(0);
            int index = 0;
            while(!stack.empty())
            {
                int numIndex = stack.pop();
                while(index <= maxIndex && nums[numIndex] >= nums[index])
                {
                    index += 1;
                }
                result[numIndex] = nums[numIndex] != nums[maxIndex] ? nums[index]:-1;
            }
            return result;
        }
    }

    题目504题

    7进制数

    给定一个整数,将其转化为7进制,并以字符串形式输出。

    思路实现

    class Solution {
        public String convertToBase7(int num) {
            char[] digits = new char[]{'0', '1', '2', '3', '4', '5', '6'};
            char[] result = new char[33];
            boolean sign = (num < 0);
            if(sign){
                num = -num;
            }
            int index = 32;
            while(num>=7)
            {
                result[index] = digits[num%7];
                num = num/7 ;
                index -= 1;
            }
            result[index] = digits[num];
            if(sign)
            {
                index -= 1;
                result[index] = '-';
            }
            return new String(result,index,33-index);
    
        }
    }

    题目506题

    相对名次

    给出 N 名运动员的成绩,找出他们的相对名次并授予前三名对应的奖牌。前三名运动员将会被分别授予 “金牌”,“银牌” 和“ 铜牌”("Gold Medal", "Silver Medal", "Bronze Medal")。

    思路实现

    class Solution {
        public String[] findRelativeRanks(int[] nums) {
            String[] res = new String[nums.length];
            HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
            for (int i = 0; i < nums.length; i++) 
            {
                map.put(nums[i], i);
            }
            Arrays.sort(nums);
            int cur = 0;
            for (int i = nums.length-1; i >= 0; i--) 
            {
                if(cur == 0)
                {
                    res[map.get(nums[i])] = "Gold Medal";
                }
                else if (cur == 1)
                {
                    res[map.get(nums[i])] = "Silver Medal";
                }
                else if (cur == 2)
                {
                    res[map.get(nums[i])] = "Bronze Medal";
                }
                else
                {
                    res[map.get(nums[i])] = Integer.toString(cur+1);
                }
                cur +=1;
            }
            return res;
        }
    }

    题目508题

    出现次数最多的子树元素和

    给你一个二叉树的根结点,请你找出出现次数最多的子树元素和。一个结点的「子树元素和」定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。

    你需要返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。

    思路

    哈希表

    实现

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        private HashMap<Integer,Integer> total = new HashMap<Integer,Integer>();
        private int maxCount = 0;
        public int[] findFrequentTreeSum(TreeNode root) 
        {
            
            dfs(root);
            List<Integer> list = new ArrayList<>();
            for (Integer key: total.keySet())
            {
                if (total.get(key) == maxCount)
                {
                    list.add((int)key);
                }
            }
            int[] res = new int[list.size()];
            for(int i = 0; i < list.size();i++)
            {
                res[i] = list.get(i);
            }
            return res;
        }
    
        private int dfs(TreeNode node)
        {
            if(node == null)
            {
                return 0;
            }
            int cur = node.val + dfs(node.left) + dfs(node.right);
            total.put(cur, total.getOrDefault(cur,0)+1);
            maxCount = Math.max(maxCount,total.get(cur));
            return cur;
        }
    }

    题目495题

    思路实现

    题目495题

    思路实现

    题目495题

    思路实现

    题目495题

    思路实现

    题目495题

    思路实现

    题目495题

    思路实现

    题目495题

    思路实现

  • 相关阅读:
    0102-进程操作(面向对象简单工厂模式,打开输入文件)
    0101-进程操作(变量命名)
    win10无法成功完成操作因为文件包含病毒或潜在的垃圾软件如何处理
    序列化和反序列化
    __slot__的用法
    python中typeguard包
    pandas如何将多个DataFrame写入同一个excel工作簿中
    DEAP库遗传算法
    【教程】如何把喜马拉雅音频下载到电脑
    oracle安装路径查看方式
  • 原文地址:https://www.cnblogs.com/mgdzy/p/14098690.html
Copyright © 2020-2023  润新知