LeetCode-hot100题解—Day7

2024-05-09 00:36
文章标签 leetcode 题解 hot100 day7

本文主要是介绍LeetCode-hot100题解—Day7,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原题链接:力扣热题-HOT100
我把刷题的顺序调整了一下,所以可以根据题号进行参考,题号和力扣上时对应的,那么接下来就开始刷题之旅吧~
1-8题见LeetCode-hot100题解—Day1
9-16题见LeetCode-hot100题解—Day2
17-24题见LeetCode-hot100题解—Day3
25-34题见LeetCode-hot100题解—Day4
39-56题见LeetCode-hot100题解—Day5
62-71题见LeetCode-hot100题解—Day6
注:需要补充的是,如果对于每题的思路不是很理解,可以点击链接查看视频讲解,是我在B站发现的一个宝藏UP主,视频讲解很清晰(UP主用的是C++),可以结合视频参考本文的java代码。

力扣hot100题解 62-71

    • 72.编辑距离
    • 75.颜色分类
    • 78.子集

72.编辑距离

思路
本题采用动态规划来解决,设f(i,j)为匹配word1中的前i个字符和word2中的前j个字符所需要的最少步数,f(i,j)的值可分为两种情况
(1)word1[i] == word2[j]:此时不需要进行任何操作即可匹配,f(i,j) = f(i-1,j-1)
(2)word1[i] != word2[j]:由于有三种操作可供选择,所以又分为三种情况,最后的结果需要在这三种情况中取最小值:

  • 插入:在word1[i]的后面插入word2[j],回到第一种情况,此时word1[i+1]
    =word2[j],所以f(i,j)=f(i,j-1)+1(这个+1是指插入操作)
  • 删除:删除word1[i],此时需要比较word1[i-1]word2[j],所以f(i,j)=f(i-1,j)+1(+1是指删除操作)
  • 替换:替换word1[i]word2[j],此时与第一种情况完全相同,f(i,j)=f(i-1,j-1)+1(+1是指替换操作)

需要注意的是,我们需要对第一行和第一列特殊处理,在两个字符串前加上空格,在初始化第一列时,f[i][0]表示word1的前i个字符匹配word2[0]的最少步骤,也就是匹配空字符串的步数,因此替换word1i个字符为空字符即可,所以步骤为i,初始化第一行同理,视频讲解点击视频讲解-编辑距离。
时间复杂度
这段代码的时间复杂度为 O(n * m),其中 nword1 的长度,mword2 的长度。
代码实现

class Solution {public int minDistance(String word1, String word2) {int n = word1.length();int m = word2.length();//给word1和word2前面添加空格,方便处理,所以在后面f数组时,长度要+1word1 = ' ' + word1;word2 = ' ' + word2;//创建二维数组并初始化int[][] f = new int[n + 1][m + 1];for(int[] item : f){Arrays.fill(item,Integer.MAX_VALUE);}//处理第一行和第一列for(int i = 0; i <= n;i++) f[i][0] = i;for(int j = 0; j <= m;j++) f[0][j] = j;for(int i = 1;i <= n;i++){for(int j = 1;j <= m;j++){if(word1.charAt(i) == word2.charAt(j)){f[i][j] = f[i - 1][j - 1];}else{f[i][j] = Math.min(f[i - 1][j - 1],Math.min(f[i - 1][j],f[i][j - 1])) + 1;}}}return f[n][m];}
}

75.颜色分类

思路
本题采用三指针解决,使用三个指针ijk来分别表示红色、白色、蓝色的分界位置,通过while循环遍历数组,当j指向的元素为0时,与i位置的元素进行交换,同时将ij都向后移动一位。当j指向的元素为2时,与k位置的元素进行交换,同时将k向前移动一位。如果j指向的元素为1,则仅将j向后移动一位。这样遍历一次数组后,就可以将数组中的0全部移动到前面,将2全部移动到后面,1的位置则自然被安排在中间。
这里说明一下为什么j指向0时交换后需要后移而指向2时交换不用后移,原因在于ij是同时从索引0处出发的,在j指向的值为2时,与k指向的值交换,此时k之前指向的值是多少我们是不知道的,可能交换后j指向的新值还需要进行交换,所以此时j指针是不用动的,k指针后移;i指针和j指针刚开始是同步的(指向0和2的时候ij要么都移动,要么都不移动),只有在指向1的时候j指针后移,i指针不动,所以可以得出j指针和i指针要么同步,要么j指针会在i指针的后面,所以i指针不会指向2(除了索引0处的值是2的情况下),只会指向0和1,且i指针前面的数全部都是0,如果还是不太理解这一点,可以自己多模拟几个例子,视频讲解点击视频讲解-颜色分类。
时间复杂度
时间复杂度为O(n),其中n为数组nums的长度。
代码实现

class Solution {public void sortColors(int[] nums) {int i = 0;int j = 0;int k =nums.length - 1;while(j <= k){if(nums[j] == 0){swapnum(nums,i,j);i++;j++;}else if(nums[j] == 2) {swapnum(nums,j,k);k--;}else j++;}}//注意:这里不能简单的交换两个数(即swap(int a,int b)),因为交换的只是形参的值,并不会影响到原始数组nums中的值//所以应该修改为交换数组中指定位置的值,而不是交换形参的值private void swapnum(int[] nums,int i,int j){int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}

78.子集

思路一深度优先搜索
本题正常解法是采用深度优先遍历来解决,枚举的方法是看每个位置的元素是否选择,当枚举到最后一个元素后,将结果添加到结果集中,注意回溯之后也要进行深度优先搜索,这样才能返回子集的全集。
时间复杂度
这个算法的时间复杂度是O(2^N),其中Nnums数组的长度。在每一层递归中,我们有两种选择:选择当前元素和不选择当前元素。因此,递归树的高度是N,每个节点有两个分支。总共有2^N个节点。所以时间复杂度是O(2^N)
代码实现

class Solution {List<List<Integer>> ans = new ArrayList<>();List<Integer> subset = new ArrayList<>();public List<List<Integer>> subsets(int[] nums) {dfs(nums,0);return ans;  }private void dfs(int[] nums,int idx){if(idx == nums.length){ans.add(new ArrayList<>(subset));return;}//添加当前元素并深度优先搜索subset.add(nums[idx]);dfs(nums,idx + 1);//丢弃当前元素并深度优先搜索,回溯subset.remove(subset.size() - 1);dfs(nums,idx + 1);}
}

思路2二进制法
由于数组中无重复元素,那么我们可以用二进制的位数来表示数组中的元素(n个元素即二进制为2^n,它的子集有2^n个),我们知道二进制是0和1的组合,当某一位为1时说明该位置对应的元素被选择了,由于二进制包含所有的组合,所以将0-2^n中所有的二进制数按照上述规则对应成子集,每一个二进制数字对应一个子集(对应位置为0即不选择,对应位置为1即选择),则可以得到子集的全集,视频讲解点击视频讲解-子集,视频中有详细的模拟举例。
时间复杂度
这段代码的时间复杂度为O(2^n * n),其中n为数组nums的长度。这是因为对于nums数组的每个元素,都有可能在子集中存在或不存在,所以一共有2^n种可能的子集组合,并且在每一种可能中,需要花费O(n)的时间来生成子集。因此,整体的时间复杂度为O(2^n * n)
代码实现

class Solution {public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> ans = new ArrayList<>();int n = nums.length;for(int mask = 0;mask < (1 << n); mask++){List<Integer> subset = new ArrayList<>();for(int i = 0; i < n; i++){//(mask & (1 << i)) != 0表示索引为i的位置对应的mask二进制为1,所以将nums[i]加进subsetif((mask & (1 << i)) != 0) subset.add(nums[i]);}ans.add(new ArrayList<>(subset));}return ans;}
}

综上,还是建议使用我们常用的dfs,简单并且耗时少。
由于力扣更新了,刷题顺序被打乱了,所以我准备调整一下刷题策略,按照知识点刷题,先讲解知识点,然后从hot100里找例题,这样更高效一点,在这里说明一下下~

这篇关于LeetCode-hot100题解—Day7的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/971893

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述