近日LeetCode算法
前言:最近刷了好多leetcode算法题,大家知道,程序=数据结构+算法,由此可见,算法真的是很重要的呢。闲话少谈,切入正题,来看看小编觉得有点意思的5题算法题吧...
1. LeetCode 73:矩阵置零 难度等级:中等
题目
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。
示例
解题思路
- 这是一个二维数组,我们只需要遍历一遍这个二维数组,把元素为0的那个位置所在的行与列分别标记起来,可以放在一个HashSet中,我们都知道,Set是一种无序不重复的集合,而List是有序可重复的,因此在这里小编选用两个Set来存储标记好的下标索引,遍历完得到这两个HashSet后,从HashSet中取得这些所有为0行列的索引后,我们就可以把原二维数组的某一行,某一列全部置为0即可。
- 值得注意的是,我们不可以一边标记一边置零,因为这样操作会影响结果,所以我们只可以遍历一遍,用来标记,再遍历一遍。用来置零。
图解
代码实现
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:提莫攻击 难度等级:中等
题目
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄,他的攻击可以让敌方英雄艾希(寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。
你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。
示例
解题思路
- 这条题目的入参是一个数组,用来记录提莫攻击的时间点,还有一个中毒的持续时间。我们可以先处理一下这个关于时间点的数组,相邻时间点的差值就是时间间隔,因此可以推出一个关于时间间隔的数组。假设时间点数组长度为n,那么时间间隔数组的长度就是n-1。得到这个时间间隔数组之后,再来处理中毒时间就很容易了
- 我们先有一个记录总中毒时间的变量,然后遍历时间间隔数组,假如间隔值大于或者等于中毒持续时间,则总中毒时间加单次中毒持续的时间;假如间隔值小于中毒持续时间,则加上间隔值即可。
图解
代码实现
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:缺失的第一个正数 难度等级:困难
题目
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
解题思路
- 求缺失的第一个正数,那个先定义一个变量j来记录,j从1开始。
- 先对原数组进行排序,然后遍历,如果遍历元素大于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.
解题思路
- 这条题目主要是模拟对url的加密与解密,通过HashMap可以很好的处理加密前与加密后的映射。
- 加密后的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
微信公众号:
原文地址:https://www.cnblogs.com/q964024886/p/11632049.html