近日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

微信公众号:

posted @ 2019-10-07 20:23  街角de男孩  阅读(210)  评论(0编辑  收藏  举报