zoukankan      html  css  js  c++  java
  • 近日LeetCode算法(记录)

    近日LeetCode算法

    前言:最近刷了好多leetcode算法题,大家知道,程序=数据结构+算法,由此可见,算法真的是很重要的呢。闲话少谈,切入正题,来看看小编觉得有点意思的5题算法题吧...

    1. LeetCode 73:矩阵置零 难度等级:中等

    题目

    给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。

    示例

    解题思路
    1. 这是一个二维数组,我们只需要遍历一遍这个二维数组,把元素为0的那个位置所在的行与列分别标记起来,可以放在一个HashSet中,我们都知道,Set是一种无序不重复的集合,而List是有序可重复的,因此在这里小编选用两个Set来存储标记好的下标索引,遍历完得到这两个HashSet后,从HashSet中取得这些所有为0行列的索引后,我们就可以把原二维数组的某一行,某一列全部置为0即可。

    2. 值得注意的是,我们不可以一边标记一边置零,因为这样操作会影响结果,所以我们只可以遍历一遍,用来标记,再遍历一遍。用来置零。

    图解

    代码实现
    package com.hx.leetcode.L_201910;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @author: wenhx
     * @date: Created in 2019/10/1 23:03
     * @description: LeetCode_73:矩阵置零
     * @level: middle
     * @status: finish
     * @version: $1.0
     */
    public class LeetCode_73 {
    
        /**
         * 将矩阵中所有0的行列置为0
         */
        public void setZeroes(int[][] matrix) {
    
            // 定义两个集合用来存放为0所有的下标
            Set<Integer> set1 = new HashSet<>();
            Set<Integer> set2 = new HashSet<>();
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix[0].length; j++) {
                    if (matrix[i][j] == 0) {
                        set1.add(i);
                        set2.add(j);
                    }
                }
            }
            // 行置为0
            for (Integer a : set1
            ) {
                for (int j = 0; j < matrix[0].length; j++) {
                    matrix[a][j] = 0;
                }
            }
            // 列置为0
            for (Integer b : set2
            ) {
                for (int i = 0; i < matrix.length; i++) {
                    matrix[i][b] = 0;
                }
            }
        }
    
        /**
         * 主方法:用来测试算法
         * @param args
         */
        public static void main(String[] args) {
    
            LeetCode_73 leetCode_73 = new LeetCode_73();
            int[][] matrix = {{0,1,2,0}, {3,4,5,2}, {1,3,1,5}};
            leetCode_73.setZeroes(matrix);
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix[0].length; j++) {
                    System.out.print(matrix[i][j] + " ");
                }
            }
        }
    }

    2. LeetCode 495:提莫攻击 难度等级:中等

    题目

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

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

    示例

    解题思路
    1. 这条题目的入参是一个数组,用来记录提莫攻击的时间点,还有一个中毒的持续时间。我们可以先处理一下这个关于时间点的数组,相邻时间点的差值就是时间间隔,因此可以推出一个关于时间间隔的数组。假设时间点数组长度为n,那么时间间隔数组的长度就是n-1。得到这个时间间隔数组之后,再来处理中毒时间就很容易了

    2. 我们先有一个记录总中毒时间的变量,然后遍历时间间隔数组,假如间隔值大于或者等于中毒持续时间,则总中毒时间加单次中毒持续的时间;假如间隔值小于中毒持续时间,则加上间隔值即可。

    图解

    代码实现
    package com.hx.leetcode.L_201910;
    
    /**
     * @author: wenhx
     * @date: Created in 2019/10/5 12:03
     * @description: LeetCode_495:提莫攻击
     * @level: middle
     * @status: finish
     * @version: $1.0
     */
    public class LeetCode_495 {
    
        /**
         * 计算中毒状态总时长
         */
        public int findPoisonedDuration(int[] timeSeries, int duration) {
    
            int sum = 0;
            if (timeSeries.length == 0) {
                return 0;
            }
            if (timeSeries.length == 1) {
                return duration;
            }
            // n个时间点有n-1个时间间隔
            int[] timeInterval = new int[timeSeries.length - 1];
            for (int i = 0; i < timeInterval.length; i++) {
                timeInterval[i] = timeSeries[i + 1] - timeSeries[i];
            }
            // 根据时间间隔来判断中毒秒数
            for (int i = 0; i < timeInterval.length; i++) {
                if (timeInterval[i] >= duration) {
                    sum += duration;
                } else {
                    sum += timeInterval[i];
                }
            }
            return sum + duration;
        }
    
        public static void main(String[] args) {
            LeetCode_495 leetCode_495 = new LeetCode_495();
            int[] timeSeries = {1, 4};
            int duration = 2;
            System.out.println("中毒状态总时长为:" + leetCode_495.findPoisonedDuration(timeSeries, duration));
        }
    }

    3. LeetCode 41:缺失的第一个正数 难度等级:困难

    题目

    给定一个未排序的整数数组,找出其中没有出现的最小的正整数。

    解题思路
    1. 求缺失的第一个正数,那个先定义一个变量j来记录,j从1开始。

    2. 先对原数组进行排序,然后遍历,如果遍历元素大于j,那么找到缺失的第一个正数;如果遍历元素大于0并且小于j,那么j自增;这里还要判断遍历元素是否有重复,因此我们可以定义一个临时变量temp来记录上一个遍历元素的值,当连续相等时则continue,j不自增。

    图解

    代码实现
    package com.hx.leetcode.L_201909;
    ​
    import java.util.Arrays;
    ​
    /**
     * @author: wenhx
     * @date: Created in 2019/9/26 09:23
     * @description: LeetCode_41:缺失的第一个正数
     * @level: hard
     * @status: finish
     * @version: $1.0
     */
    public class LeetCode_41 {
    ​
        /**
         * 计算缺失的第一个正数
         */
        public int firstMissingPositive(int[] nums) {
            // 对数组进行排序
            Arrays.sort(nums);
            // 定义一个从1开始自增的正数
            int j = 1;
            // 定义一个临时变量,用来判断相邻值是否相同
            int temp = 0;
            for (int i = 0; i < nums.length; i++) {
                // 当数组中某值大于自增j时
                if (nums[i] > j) {
                    return j;
                }
                // 当数组中某值大于0并且不大于j时
                else if (nums[i] > 0 && nums[i] <= j) {
                    // 数组中连续一样
                    if (temp == nums[i]) {
                        continue;
                    }
                    j++;
                } else {
                    continue;
                }
                // 更新临时变量
                temp = nums[i];
            }
            return j;
        }
    ​
        public static void main(String[] args) {
    ​
            LeetCode_41 leetCode_41 = new LeetCode_41();
            int[] nums = {1, 2, 0};
            System.out.println("缺失的第一个正数为:" + leetCode_41.firstMissingPositive(nums));
        }
    ​
    }

    4. LeetCode 535:TinyURL的加密与解密 难度等级:中等

    题目

    TinyURL是一种URL简化服务。要求:设计一个 TinyURL 的加密 encode 和解密 decode 的方法。你的加密和解密算法如何设计和运作是没有限制的,你只需要保证一个URL可以被加密成一个TinyURL,并且这个TinyURL可以用解密方法恢复成原本的URL。

    示例

    当你输入一个URL https://leetcode.com/problems/design-tinyurl

    它将返回一个简化的URL http://tinyurl.com/4e9iAk.

    解题思路
    1. 这条题目主要是模拟对url的加密与解密,通过HashMap可以很好的处理加密前与加密后的映射。

    2. 加密后的url前缀格式有“http://tinyurl.com/”,问题是后面的6位随机码如何产生呢?很简单,自己写一个算法呗!看下列代码,可复用喔~

    图解

    代码实现
    package com.hx.leetcode.L_201910;
    ​
    import java.util.HashMap;
    import java.util.Random;
    ​
    /**
     * @author: wenhx
     * @date: Created in 2019/10/7 11:44
     * @description: LeetCode_535:TinyURL的加密与解密
     * @level: middle
     * @status: finish
     * @version: $1.0
     */
    public class LeetCode_535 {
    ​
        private HashMap hashMap = new HashMap<String, String>();
    ​
        /**
         * 加密:将一个长的url转换为一个短的url
         * @param longUrl
         * @return
         */
        public String encode(String longUrl) {
            String keyString = "http://tinyurl.com/" + getRandomString(6);
            hashMap.put(keyString, longUrl);
            return keyString;
        }
    ​
        /**
         * 解密:将一个短的url转换为一个长的url
         * @param shortUrl
         * @return
         */
        public String decode(String shortUrl) {
            return (String) hashMap.get(shortUrl);
        }
    ​
        /**
         * 自定义方法:产生6位数的字符串随机码
         * @param length
         * @return
         */
        public static String getRandomString(int length) {
            String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < length; i++) {
                int number = random.nextInt(62);
                sb.append(str.charAt(number));
            }
            return sb.toString();
        }
    ​
        /**
         * 主方法:用来测试一下
         * @param args
         */
        public static void main(String[] args) {
            LeetCode_535 codec = new LeetCode_535();
            String longUrl = "https://leetcode.com/problems/design-tinyurl";
            String shortUrl = codec.encode(longUrl);
            System.out.println("加密后的url是:" + shortUrl);
            System.out.println("解密后的url是:" + codec.decode(shortUrl));
        }
    }

    5. LeetCode 20:有效的括号 难度等级:简单

    题目

    给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

    有效字符串需满足:

    左括号必须用相同类型的右括号闭合。
    左括号必须以正确的顺序闭合。

    注意空字符串可被认为是有效字符串。

    示例

    解题思路

    这里括号的匹配,用栈可以很好地解决这个问题。我们都知道,栈是一个后进先出的数据结构,将一个具有()[]{}的字符串从后面开始,一个一个地压入栈中,压第一个,然后再拿字符串中相对最后一个括号与栈中栈顶元素匹配,例如 ")"与"("匹配,"]"与"["匹配,"}"与"{"匹配。这里值得注意的是,栈顶的括号必须是右括号,而字符串尾部的括号必须是左括号。

    图解

    代码实现
    package com.hx.leetcode.L_Before;
    ​
    import java.util.Stack;
    ​
    /**
     * @author: wenhx
     * @date: Created in 2019/9/25 10:58 (之前)
     * @description: LeetCode_20:有效的括号
     * @level: simple
     * @status: finish
     * @version: $1.0
     */
    public class LeetCode_20 {
    ​
        /**
         * 计算是否有效的括号
         */
        public boolean isValid(String s) {
            Stack<String> m = new Stack<>();
            while (!s.isEmpty()) {
                if (m.empty()) {
                    m.push(s.substring(s.length() - 1));
                } else {
                    if (m.peek().equals(")") && s.substring(s.length() - 1).equals("(")
                        || m.peek().equals("]") && s.substring(s.length() - 1).equals("[")
                        || m.peek().equals("}") && s.substring(s.length() - 1).equals("{")) {
                        m.pop();
                    } else {
                        m.push(s.substring(s.length() - 1));
                    }
                }
                s = s.substring(0, s.length() - 1);
            }
            if (m.empty()) {
                return true;
            } else {
                return false;
            }
        }
    ​
        public static void main(String[] args) {
    ​
            LeetCode_20 leetCode_20 = new LeetCode_20();
            String s = "{[]}()";
            System.out.println(leetCode_20.isValid(s));
        }
    }

    好啦,今天就先到这啦,以上算法纯属小编个人想法,如有疑惑可以私信或者留言,蟹蟹大家。一起谈论,一起进步。

    小伙伴们后续有时间小编会经常跟新的嘿嘿...

    后续

    个人博客地址:https://www.cnblogs.com/q964024886/

    GitHub地址:https://github.com/wenhaixiong

    微信公众号:

  • 相关阅读:
    算法学习 -- 枚举
    一个简单程序的汇编执行过程分析
    计算思维(二) -- 符号化、计算化与自动化
    小记:vue 及 react 的工程项目入口小结及 webpack 配置多页面应用参考
    小记:iOS 中一般对于 view 不依赖 model 的的两种代码书写形式
    mac 下使用 ikbcG87 及使用 karabiner 改大小写键
    基于 svn 服务器及 cocoapods-repo-svn 插件进行组件化私有库的创建
    RxSwift 入坑好多天
    基于 socket.io, 简单实现多平台类似你猜我画 socket 数据传输
    基于 GCDAsyncSocket,简单实现类似《你猜我画》的 socket 数据传输
  • 原文地址:https://www.cnblogs.com/q964024886/p/11632049.html
Copyright © 2011-2022 走看看