我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情
一、前言
由于单纯地算法题是真的不给推荐, 也有可能是太简单了。。
所以接下来采取多天发一次的方式,记录一下算法小白的历练之路
注:刷题语言均为java,每天保证做三道以前没有做过的题目,刷遍LeetCode从今天开始
2022/8/29
从今天第二道题开始就是哈希表相关的题了
142. 环形链表 II
题目描述
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例
示例1
输入: head = [3,2,0,-4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。
示例2
输入: head = [1,2], pos = 0
输出: 返回索引为 0 的链表节点
解释: 链表中有一个环,其尾部连接到第一个节点。
示例3
输入: head = [1], pos = -1
输出: 返回 null
解释: 链表中没有环。
提示
- 链表中节点的数目范围在范围
[0, 104]
内 -105 <= Node.val <= 105
pos
的值为-1
或者链表中的一个有效索引
解题思路
- 首先,我们要去判断当前链表 head是不是环形链表
- 新建两个链表 nodeA和 nodeB,去接收原链表 head
- 循环遍历,nodeA每次前进一步,nodeB每次前进两步
- 当链表相遇时,证明链表 head是环形链表
- 如果不是环形链表,则直接返回 null
- 如果是环形链表,那么 nodeA肯定会与 nodeB相遇
- 因为 nodeA每次前进一步,nodeB每次前进两步,所以 nodeA绕环形链表部分走一圈时,nodeB会绕环形链表走两圈,这期间不论环形链表部分是单数链表还是双数链表,肯定会相遇最少一次
- 现在我们确定了链表 head是环形链表之后,该去判断环形链表部分的初始节点位置,下面简称为入环点
- 假设链表 head的头结点到入环点的距离为 x,入环点到相遇点为 y,相遇点到入环点为 z
- 那么 nodeA走到相遇点的距离为 x + y
- nodeB走到相遇点的距离为 n(y + z) + x + y
- 又因为 nodeA走一步,nodeB走两步,所以: (x + y)* 2 = n(y + z) + x + y
- 解得: x = n(y + z) -y
- 整理可得: x = (n - 1)(y + z) + z
- 因为 nodeA跑一步 nodeB跑两步,所以 n是肯定大于 1的
- 又因为环形链表部分的长度等于 y + z
- 所以 x = z + nodeA绕环形链表圈数
- 那么我们现在要做的,就是让 nodeA跑 x距离,让 nodeB跑 (z + n圈)
- 所以我们让 nodeA = head,让 nodeA从头开始跑
- nodeB不变,因为当前 nodeB距离入环点就是 z的距离
- 同时让 nodeA和 nodeB每次循环前进一位,保证两个节点肯定会在入环点相遇
- 具体代码如下所示
代码展示
public static ListNode detectCycle(ListNode head) {
// 搞两个链表,接收 head
// A是慢链表,B是快链表
ListNode nodeA = head;
ListNode nodeB = head;
// 判断该链表是否为环形链表
boolean flag = false;
while(nodeB != null && nodeB.next != null){
nodeA = nodeA.next;
nodeB = nodeB.next.next;
if (nodeA == nodeB){
flag = true;
break;
}
}
// 如果为环形链表,判断入口位置
if (flag){
nodeA = head;
while(nodeA != nodeB){
nodeA = nodeA.next;
nodeB = nodeB.next;
}
return nodeA;
}
return null;
}
提交结果
242. 有效的字母异位词
题目描述
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例
示例1
输入: s = "anagram", t = "nagaram"
输出: true
示例2
输入: s = "rat", t = "car"
输出: false
提示
1 <= s.length, t.length <= 5 * 104
s
和t
仅包含小写字母
解题思路
- 将字符串转化为 char数组,数组长度为 26
- 根据 ASCII可以计算出字幕在数组中的下标
- 遍历字符串s,在数组相应的位置上进行 +1操作
- 遍历字符串t,在数组相应的位置上进行 -1操作
- 最后遍历我们的 char数组
- 如果数组中有元素不为 0,则字符串s 和字符串t 不是字母异位词
代码展示
public static boolean isAnagram(String s, String t) {
int[] array = new int[26];
char[] charsS = s.toCharArray();
char[] charsT = t.toCharArray();
for (int i = 0; i < charsS.length; i++) {
array[charsS[i] - 'a'] ++;
}
for (int i = 0; i < charsT.length; i++) {
array[charsT[i] - 'a'] --;
}
for (int i = 0; i < array.length; i++) {
if (array[i] != 0){
return false;
}
}
return true;
}
提交结果
383.赎金信
题目描述
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。
示例
示例1
输入: ransomNote = "a", magazine = "b"
输出: false
示例2
输入: ransomNote = "aa", magazine = "ab"
输出: false
示例3
输入: ransomNote = "aa", magazine = "aab"
输出: true
提示
1 <= ransomNote.length, magazine.length <= 105
ransomNote
和magazine
由小写英文字母组成
解题思路
- 本题是上一题的相关类型题,解题思路也差不多
- 字符串 ransomNote的长度是永远小于等于字符串 magazine的
- 所以还是创建一个长度为 26的数组
- 遍历 ransomNote每个元素减去 ‘a’的 ASCII码, 获取到数组的下标进行 ++ 操作
- 遍历 magazine每个元素减去 ‘a’的 ASCII码, 获取到数组的下标进行 -- 操作
- 遍历数组,看是否有元素是大于0的,有则false
代码展示
public static boolean canConstruct(String ransomNote, String magazine) {
int[] array = new int[26];
for (char c : ransomNote.toCharArray()) {
array[c - 'a']++;
}
for (char c : magazine.toCharArray()) {
array[c - 'a']--;
}
for (int i : array) {
if (i > 0){
return false;
}
}
return true;
}
提交结果
2022/8/30
49. 字母异位词分组
题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例
示例1
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例2
输入: strs = [""]
输出: [[""]]
示例3
输入: strs = ["a"]
输出: [["a"]]
提示
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i]
仅包含小写字母
解题思路
- 设置int[26]数组,存放 a-z的个数
- 使用 ASCII 字母 - ‘a’ 获取到对应的数组下标
- 字符串 p永远比字符串 s短
- 所以获取字符串 p对应的字母下标数组
- 遍历字符串 s,长度为 p的长度
- 这里注意终止条件为 s.lenght - p.lenght + 1
- 判断当前长度的字符串与 p是否为异步词
- 如果是异步词则加入返回 list中
注意:判断两个数组是否相等可以使用 Arrays.equlas(int[] int1, int[] int2) 遍历字符串s 时的中止条件应该是 s.lenght - p.lenght + 1
代码展示
public static List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<>();
// 求出 p的长度
int lengthP = p.length();
// 字符串 s转换成 char数组
char[] chars = s.toCharArray();
// 获取 p的哈希表
int[] array = new int[26];
for (char c : p.toCharArray()) {
array[c -'a'] ++;
}
// 循环遍历
for (int i = 0; i < chars.length - lengthP + 1; i++) {
int[] array1 = new int[26];
for (int j = 0; j < lengthP ; j++) {
array1[chars[i + j] - 'a']++;
}
// 判断当前长度的字符串是否和p是异步词
if (Arrays.equals(array, array1)){
list.add(i);
}
}
return list;
}
提交结果
438. 找到字符串中所有字母异位词
题目描述
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
示例
示例1
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例2
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
提示
1 <= s.length, p.length <= 3 * 104
s
和p
仅包含小写字母
解题思路
-
这个代码改的难受的一批,可以简写很多,感兴趣的自己敲一下
-
先定义了返回的集合
-
使用map去判断是不是字母异味词
-
开始遍历
-
使用老办法 array数组存储单词字母的个数
-
加入map, 这里注意,array.toString记录的是数组的内存地址,而不是值,所以map的 key不能直接记录
-
String.valueOf方法去记录还是获取的元素的 toString方法,所以这里需要用 Arrays.toString获取真正的数组元素信息
-
剩下的就是map判断,然后遍历出map里的 value信息了
注意:数组的toString方法返回值是内存地址 效率很低,一个是因为自己代码的问题,例如最后的遍历map可以使用 stream 流来做 还有一部分原因是,我看大佬们的解题是在获取到单词的字母的时候,也是做了一个str.toCharArray()操作,但是在这里是使用了 排序,保持字母顺序的一个固定key, 存到map中了
代码展示
public static List<List<String>> groupAnagrams(String[] strs) {
// 定义返回值
List<List<String>> result = new ArrayList<>();
// 存储相同字母的单词
Map<String, List<String>> map = new HashMap<>();
// 遍历 strs
int[] array = new int[26];
String s, t;
for (String str : strs) {
for (char c : str.toCharArray()) {
array[c - 'a']++;
}
List<String> strings;
s = String.valueOf(Arrays.toString(array));
if (map.containsKey(s)) {
strings = map.get(s);
}else{
strings = new ArrayList<>();
}
strings.add(str);
map.put(s, strings);
array = new int[26];
}
for (Map.Entry<String, List<String>> listEntry : map.entrySet()) {
result.add(listEntry.getValue());
}
return result;
}
提交结果
383.赎金信
题目描述
解题思路
- 遍历出所有的值
- 找出重复的值
- 很明显使用set去做
- 第一个set存 num1的值
- 遍历 num2的时候判断这个值在 set1中是否存在,若存在则表示重复
- 最后使用 stream的方式提取出 int数组
代码展示
public static int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
后
for (int i : nums1) {
set1.add(i);
}
for (int i : nums2) {
if (set1.contains(i)) {
set2.add(i);
}
}
int[] ints = set2.stream().mapToInt(s -> s).toArray();
return ints;
}
提交结果
2022/8/31
350. 两个数组的交集 II
题目描述
解题思路
- 两个数组的交集,就是找出这两个数组中相同的元素
- 先将两个数组进行排序操作
- 创建 int x,使用三元运算获取到两个数组的最小长度
- 两个数组最大的交集长度 == x
- 创建数组 result,长度为 x,用来接收两个数组的交集
- 遍历两个数组
- 因为之前我们给两个数组进行过排序了,所以直接判断然后下标 ++就可以了
- 具体实现和双指针一样
代码展示
public static int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int i = 0,j = 0, z = 0;
int x = nums1.length < nums2.length ? nums1.length: nums2.length;
int[] result = new int[x];
while(j < nums2.length && i < nums1.length){
if (nums1[i] == nums2[j]){
result[z] = nums1[i];
i++;
j++;
z++;
} else if (nums1[i] < nums2[j]) {
i++;
}else{
j++;
}
}
int[] ints = Arrays.copyOf(result, z);
return ints;
}
提交结果
202 快乐数
题目描述
解题思路
- 读题可知,就是一个数字的各个位的平方相加
- 题中有说,可能会陷入死循环,结果永远不唯一
- 所以我们要采用 Set对每次获取到的结果进行判断是不是出现过
- 出现过代表陷入了死循环中
代码展示
public static boolean isHappy(int n) {
Set<Integer> set = new HashSet<>();
while(n != 1 && !set.contains(n)){
set.add(n);
n = test(n);
}
return n == 1;
}
private static Integer test(int n){
int result = 0;
while(n > 0){
int temp = n % 10;
result += temp * temp;
n = n / 10;
}
return result;
}
提交结果
1. 两数之和 (之前做过, 不算)
题目描述
解题思路
- 这道题我就通过了一种很简单的做法
- 遍历当前值
- 目标值减去 当前值 == 需要值
- 如果需要值在 map中则直接返回
- 若不在则存储到 map中
代码展示
public static int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (map.containsKey(temp)) {
return new int[]{i, map.get(temp)};
}else{
map.put(nums[i], i);
}
}
return null;
}
提交结果
454. 四数相加 II
题目描述
解题思路
- 和上面两数之和一样的
- 两两个数组遍历相加存到map
- 获取需要值然后去map中取
- 和上一题不一样的是,这次是找到个数
代码展示
public static int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = new HashMap<>();
int num = 0;
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
num = nums1[i] + nums2[j];
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
}
}
int result = 0;
for (int i = 0; i < nums3.length; i++) {
for (int j = 0; j < nums4.length; j++) {
num = 0 - (nums3[i] + nums4[j]);
int count = map.getOrDefault(num, 0);
result += count;
}
}
return result;
}
提交结果
2022/9/1
15. 三数之和
题目描述
解题思路
- 因为题中只要求返回 0且不重复的数组,而没有要求顺序
- 所以我们可以使用双指针来做这道题
- 先对数组进行排序
- 设置三个指针
- 指针 i从 0开始,从左向右前进
- 指针 left从 1开始,从左向右前进
- 指针 right从 lenght-1 开始,从右向左前进
- 题中要求不重复数组,那么采用三指针的情况肯定就不会有重复的数值了,因为我们的数组是排序过的
- 因为 left肯定比 i大,且是从左向右前进,right是从右向左前进,那么循环终止条件为 left >= right
- 计算当前三指针元素之和是否等于目标值 target
- 小了就 left++
- 大了就 right--
- 注意,这里需要判断当前 i下标元素是否和 i-1下标元素相同,相同则跳出循环,因为要求数组是不重复的
代码展示
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {
return result;
}
if (i > 0 && nums[i] == nums[i - 1]){
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (left < right){
int sum = nums[i] + nums[left] + nums[right];
if (sum < 0){
left++;
}else if (sum > 0){
right--;
}else{
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
while(right > left && nums[right] == nums[right - 1]) right--;
while(right > left && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
}
}
return result;
}
提交结果
18. 四数之和
题目描述
解题思路
这道题和三数之和的思路是一样的,区别就是多加了一层循环,这层循环是从 lenght-1开始的
建议大家看懂了上一题三数之和之后自己尝试着做一下
代码展示
public static List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > target && (nums[i] > 0 || target > 0)){
return list;
}
if (i > 0 && nums[i] == nums[i - 1]){
continue;
}
for (int j = nums.length - 1; j > i; j--) {
if (j < nums.length - 1 && nums[j] == nums[j + 1]){
continue;
}
int left = i + 1;
int right = j - 1;
while (left < right){
long num = (long) nums[i] + nums[left] + nums[right] + nums[j];
if (num < target){
left++;
}else if (num > target){
right--;
}else{
list.add(Arrays.asList(nums[i],nums[left],nums[right],nums[j]));
while(left < right && nums[right] == nums[right - 1]) right--;
while(left < right && nums[left] == nums[left + 1]) left++;
left++;
right--;
}
}
}
}
return list;
}
提交结果
本题小结
- 注意 nums[i] 的范围, 需要用 long接收
344. 反转字符串
题目描述
解题思路
直接暴力破解。。
代码展示
public static void reverseString(char[] s) {
for (int i = 0; i < s.length / 2; i++) {
char temp = s[i];
s[i] = s[s.length - 1 - i];
s[s.length - 1 - i] = temp;
}
}
提交结果
题目小结
该题于去年做过,不算今日完成
541. 反转字符串 II
题目描述
解题思路
- 这道题的我感觉比上道题烦很多
- 做字符串相关的题我比较喜欢将其转为 char数组做,大家可以根据自己的喜好来
- 初始化每次反转的字符长度以及下标 left和 right
- 循环遍历来反转字符串
- 循环中止条件是 right >= s.lenght
- 求出每次反转的最后一个字符的下标, stop
- 循环反转字符串
- 反转完毕之后 left=right 同时 right+= 2*k
- 题中根据剩余字符的不同来做了不同的操作
- 我们判断出最后一次循环的终止位置 right
- 循环反转字符串
代码展示
public static String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
int left = 0;
int right = left + 2 * k;
while (right < s.length()){
int stop = left + k - 1;
while(left < stop){
char temp = chars[left];
chars[left] = chars[stop];
chars[stop] = temp;
left++;
stop--;
}
left = right;
right += 2 * k;
}
right = s.length() - left < k ? s.length() - 1 : left + k -1 ;
while (left < right){
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
return String.valueOf(chars);
}
提交结果
题目小结
- 一定一定要计算好边界,不然很容易出错
2022/9/2
剑指 Offer 05. 替换空格
题目描述
解题思路
- 依旧是字符串转为 char数组
- 因为是把空格转为 %20,所以我们新的字符串长度有所变化
- 遍历字符串求出新数组长度
- 创建新数组
- 倒序遍历字符串
- 如果当前 i == lenght 那么说明剩余的字符串内没有空格,直接返回就可以了
- 如果当前字符为空格,则在数组中倒序加入 02%
代码展示
public static String replaceSpace(String s) {
char[] chars = s.toCharArray();
int length = s.length();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == ' '){
length += 2;
}
}
char[] ints = new char[length];
for (int i = chars.length - 1; i >= 0; i--) {
if (i == length){
return String.valueOf(ints);
}
if (chars[i] == ' '){
ints[--length] = '0';
ints[--length] = '2';
ints[--length] = '%';
}else{
ints[--length] = chars[i];
}
System.out.println(Arrays.toString(ints));
}
return String.valueOf(ints);
}
提交结果
151. 反转字符串中的单词
题目描述
解题思路
- 和上一题一样的
- 创建List
- 转为char数组
- 遍历字符串
- 新建StringBuilder对象 str
- 如果有空格且 str不为空则把 str加入到 list中
- 最后倒序遍历相加到一起
代码展示
public static String reverseWords(String s) {
List<String> list = new ArrayList<>();
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
StringBuilder str = new StringBuilder();
while(i < chars.length && chars[i] != ' '){
str.append(chars[i]);
i++;
}
if (str != null){
list.add(str.toString());
}
}
StringBuilder str = new StringBuilder();
for (int i = list.size() - 1; i >= 0; i--) {
str.append(list.get(i));
str.append(" ");
}
str.deleteCharAt(str.length() - 1);
return str.toString();
}
提交结果##
小题总结
- 两次判断当前char是否为 ‘ ’, 一次在循环开始,一次在获取单词
剑指Offer58-II.左旋转字符串
题目描述
解题思路
- 反转 0-n
- 反转 n-length
- 反转 0-length
代码展示
public String reverseLeftWords(String s, int n) {
char[] chars = s.toCharArray();
int length = chars.length;
int t = n;
for (int i = 0; i < n; i++) {
n--;
char temp = chars[i];
chars[i] = chars[n];
chars[n] = temp;
}
for (int i = t; i < length; i++) {
char temp = chars[i];
chars[i] = chars[length - 1];
chars[length - 1] = temp;
length--;
}
length = chars.length;
for (int i = 0; i < length; i++) {
char temp = chars[i];
chars[i] = chars[length - 1];
chars[length - 1] = temp;
length--;
}
return String.valueOf(chars);
}
提交结果
2022/9/3
28. 实现 strStr()
题目描述
解题思路
本体是采用了暴力破解的方式,但是这道题是 KMP算法的经典题目
在我的文章从 KMP算法到 Java的 String.indexOf(String str)方法 中介绍了KMP算法及其解题思路
代码展示
public static int strStr(String haystack, String needle) {
char[] chars = haystack.toCharArray();
char[] chars1 = needle.toCharArray();
for (int i = 0; i < chars.length; i++) {
int n = 0;
int m = i;
while(m < chars.length && n < chars1.length && chars[m] == chars1[n]){
m++;
n++;
}
if (n == chars1.length && chars[m - 1] == chars1[n - 1]){
return i;
}
}
return -1;
}
提交结果
459. 重复的子字符串
题目描述
解题思路
- 一样的,也是通过了KMP算法来做
代码展示
public boolean repeatedSubstringPattern(String s) {
if (s.equals("")) return false;
int len = s.length();
// 原串加个空格(哨兵),使下标从1开始,这样j从0开始,也不用初始化了
s = " " + s;
char[] chars = s.toCharArray();
int[] next = new int[len + 1];
// 构造 next 数组过程,j从0开始(空格),i从2开始
for (int i = 2, j = 0; i <= len; i++) {
// 匹配不成功,j回到前一位置 next 数组所对应的值
while (j > 0 && chars[i] != chars[j + 1]) j = next[j];
// 匹配成功,j往后移
if (chars[i] == chars[j + 1]) j++;
// 更新 next 数组的值
next[i] = j;
}
// 最后判断是否是重复的子字符串,这里 next[len] 即代表next数组末尾的值
if (next[len] > 0 && len % (len - next[len]) == 0) {
return true;
}
return false;
}
提交结果
2022/9/4
232. 用栈实现队列
题目描述
解题思路
具体可以看我的文章 你有用过 java中的栈和队列吗?怎么用栈来实现队列呢
提交结果
225. 用队列实现栈
题目描述
解题思路
- 使用两个队列
- in队列模拟栈
- out队列保存临时数据
- 新增的时候,将数值存到 outQueue中
- 然后将 inQueue中的数据加入到 outQueue中
- 又将 outQueue赋值给 inQueue
代码展示
public class MyStack {
Queue<Integer> inQueue ;
Queue<Integer> outQueue ;
public MyStack() {
inQueue = new LinkedList<>();
outQueue = new LinkedList<>();
}
public void push(int x) {
outQueue.offer(x);
while(!inQueue.isEmpty()){
outQueue.offer(inQueue.poll());
}
Queue<Integer> temp ;
temp = inQueue;
inQueue = outQueue;
outQueue = temp;
}
public int pop() {
return inQueue.poll();
}
public int top() {
return inQueue.peek();
}
public boolean empty() {
return inQueue.isEmpty();
}
}
提交结果
20. 有效的括号
题目描述
解题思路
- 新建一个队列
- 遍历字符串
- 如果当前字符串为 左括号,则队列中存储右括号
- 如果当前字符串为 右括号,则判断当前队列是否为空,且队列首元素是否相等
- 弹出当前队列首元素
- 最后判断队列中是否还有值
- 有值则不匹配
这道题是完全借鉴了代码随想录,我自己写的方式和这个真的相差甚远,观感性太差了
代码展示
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
//碰到左括号,就把相应的右括号入栈
if (ch == '(') {
deque.push(')');
}else if (ch == '{') {
deque.push('}');
}else if (ch == '[') {
deque.push(']');
// 栈为空或者栈顶元素与当前 ch不匹配,则返回 false
} else if (deque.isEmpty() || deque.peek() != ch) {
return false;
}else {
// 栈不为空,且栈顶元素与 ch一致
deque.pop();
}
}
//最后判断栈中元素是否匹配
return deque.isEmpty();
}
提交结果
碎碎念
我都是先做的题目,最后统一总结的解题思路
才发现,九月三号少做了一题,少了20积分,真的是出师不利
本文内容到此结束了
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位大佬指出。
我是 宁轩 , 我们下次再见