力扣大厂热门面试算法题 30-32

        30. 串联所有单词的子串,31. 下一个排列 ,32. 最长有效括号,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.15 可通过leetcode所有测试用例。

目录

30. 串联所有单词的子串

解题思路

完整代码

Java

Python

31. 下一个排列

解题思路

完整代码

Java

Python

32. 最长有效括号

解题思路

完整代码

Java

Python


30. 串联所有单词的子串

给定一个字符串 s 和一个字符串数组 words words 中所有字符串 长度相同

 s 中的 串联子串 是指一个包含  words 中所有字符串以任意顺序排列连接起来的子串。

  • 例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd""cdabef", "cdefab""efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。

返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。

示例 1:

输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。

示例 2:

输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。

示例 3:

输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
输出:[6,9,12]
解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。
子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。
子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。
子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。

解题思路

  1. 理解问题:给定一个主字符串 s 和一个字符串数组 wordswords 中所有字符串长度相同。需要找到 s 中所有包含 words 中所有字符串以任意顺序连接形成的子串的起始索引。

  2. 初始化:由于 words 中的所有字符串长度相同,我们可以计算出每个串联子串的总长度,即 wordLength * words.size()。接下来,我们可以在主字符串 s 中遍历长度为此值的所有子串。

  3. 滑动窗口:使用滑动窗口的方法来检查 s 中的每个可能的子串。窗口大小为串联子串的总长度。

  4. 哈希表:使用两个哈希表,一个用来存储 words 数组中单词的出现次数,另一个用来存储当前窗口中与 words 中单词相匹配的单词出现次数。

  5. 遍历:从 s 的第0个字符开始,遍历到 s.length() - windowSize 为止。对于每个可能的子串,使用哈希表来检查是否包含了 words 中所有单词的正确数量。如果是,则将当前子串的起始索引添加到结果列表中。

  6. 返回结果:遍历完成后,返回所有找到的起始索引。

完整代码

Java
public class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> result = new ArrayList<>();if (s == null || s.length() == 0 || words == null || words.length == 0) {return result;}int wordLen = words[0].length();int windowLen = wordLen * words.length;Map<String, Integer> wordMap = new HashMap<>();for (String word : words) {wordMap.put(word, wordMap.getOrDefault(word, 0) + 1);}for (int i = 0; i <= s.length() - windowLen; i++) {Map<String, Integer> seenWords = new HashMap<>();int j = 0;while (j < words.length) {String word = s.substring(i + j * wordLen, i + (j + 1) * wordLen);if (wordMap.containsKey(word)) {seenWords.put(word, seenWords.getOrDefault(word, 0) + 1);if (seenWords.get(word) > wordMap.get(word)) {break;}} else {break;}j++;}if (j == words.length) {result.add(i);}}return result;}
}
Python
class Solution:def findSubstring(self, s: str, words: List[str]) -> List[int]:if not s or not words:return []word_length = len(words[0])word_count = len(words)window_length = word_length * word_countword_map = {}for word in words:if word in word_map:word_map[word] += 1else:word_map[word] = 1results = []for i in range(len(s) - window_length + 1):seen_words = {}for j in range(0, window_length, word_length):word = s[i + j:i + j + word_length]if word in word_map:if word in seen_words:seen_words[word] += 1else:seen_words[word] = 1if seen_words[word] > word_map[word]:breakelse:breakelse:results.append(i)return results

31. 下一个排列

整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。

  • 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3][1,3,2][3,1,2][2,3,1] 。

整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

  • 例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
  • 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
  • 而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。

给你一个整数数组 nums ,找出 nums 的下一个排列。

必须 原地 修改,只允许使用额外常数空间。

示例 1:

输入:nums = [1,2,3]
输出:[1,3,2]

示例 2:

输入:nums = [3,2,1]
输出:[1,2,3]

示例 3:

输入:nums = [1,1,5]
输出:[1,5,1]

解题思路

  1. 从右向左查找:首先从数组的末尾开始向前查找,找到第一个不满足递增关系的元素,记为 nums[i]。这意味着从 nums[i+1]nums[n-1](其中 n 是数组的长度)这部分是按降序排列的。

  2. 查找交换位置:如果找到了这样的 nums[i],再次从数组的末尾开始向前查找,找到第一个大于 nums[i] 的元素,记为 nums[j]

  3. 交换元素:交换 nums[i]nums[j]

  4. 反转子数组:最后,将从 i+1 到数组末尾的部分反转,因为原来这部分是降序的,反转之后变为升序,这样就可以得到下一个排列。

        如果整个数组都是降序排列的,那么它已经是最大的排列,按照题目要求,应该重排为最小排列,即其元素按升序排列。这可以通过直接反转整个数组来实现。

完整代码

Java
public class Solution {public void nextPermutation(int[] nums) {int i = nums.length - 2;while (i >= 0 && nums[i] >= nums[i + 1]) {i--;}if (i >= 0) {int j = nums.length - 1;while (nums[j] <= nums[i]) {j--;}swap(nums, i, j);}reverse(nums, i + 1);}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}private void reverse(int[] nums, int start) {int i = start, j = nums.length - 1;while (i < j) {swap(nums, i, j);i++;j--;}}
}
Python
class Solution:def nextPermutation(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""# Step 1: 从右向左找到第一个不是递增的数字i = len(nums) - 2while i >= 0 and nums[i] >= nums[i + 1]:i -= 1# Step 2: 如果找到了这样的数字,再找一个比它大的最小数字进行交换if i >= 0:j = len(nums) - 1while nums[j] <= nums[i]:j -= 1# 交换这两个数字nums[i], nums[j] = nums[j], nums[i]# Step 3: 将 i 之后的数字反转,确保是下一个最小的排列left, right = i + 1, len(nums) - 1while left < right:nums[left], nums[right] = nums[right], nums[left]left, right = left + 1, right - 1

32. 最长有效括号

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号

子串

的长度。

示例 1:

输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"

示例 2:

输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"

示例 3:

输入:s = ""
输出:0

解题思路

我们可以使用栈。栈可以帮助我们跟踪未匹配的括号,并且可以用来找出有效子串的长度。具体的做法如下:

  1. 初始化:创建一个栈,并将 -1 推入栈中。这一步是为了在一开始时,栈底有一个元素,便于后面计算长度。

  2. 遍历字符串:遍历给定字符串的每个字符。

    • 如果当前字符是 '(',将其索引推入栈中。
    • 如果当前字符是 ')',首先弹出栈顶元素。
      • 如果此时栈变为空,将当前索引推入栈中。这是因为这个右括号可能是下一个有效子串的起始点的前一个位置。
      • 如果栈不为空,则计算当前有效子串的长度,方法是当前索引减去栈顶元素。更新最长有效括号子串的长度。
  3. 返回结果:在遍历完整个字符串后,最长有效括号子串的长度就被找到了。

完整代码

Java

public class Solution {public int longestValidParentheses(String s) {int maxLength = 0;Stack<Integer> stack = new Stack<>();stack.push(-1);  // 初始时压入-1,便于后续计算长度for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {stack.push(i);  // 将左括号的索引压入栈中} else {stack.pop();  // 遇到右括号,弹出栈顶元素if (stack.isEmpty()) {stack.push(i);  // 如果栈为空,压入当前索引作为新的基准} else {maxLength = Math.max(maxLength, i - stack.peek());  // 计算当前有效子串长度}}}return maxLength;}
}
Python
class Solution:def longestValidParentheses(self, s: str) -> int:max_length = 0stack = [-1]for i, char in enumerate(s):if char == '(':stack.append(i)else:stack.pop()if not stack:stack.append(i)else:max_length = max(max_length, i - stack[-1])return max_length

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/748391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法笔记 连载中。。。

HashMap&#xff08;会根据key值自动排序&#xff09; HashMap<String, Integer> hash new HashMap<>() hash.put(15,18) hash.getOrDefault(ts, -1) //如果ts(key)存在&#xff0c;返回对应的value 否则返回-1 hashMap1.get(words1[i])1会报错&#xff0c;因…

AcWing 848. 有向图的拓扑序列

#include<iostream> #include<cmath> #include<queue> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int N1e510; int n,m,a,b; int e[N],ne[N],h[N],idx; int d[N],top[N],cnt1;//top是拓扑排序…

Linux学习笔记:什么是文件描述符

什么是文件描述符 C语言的文件接口文件的系统调用什么是文件描述符,文件描述符为什么是int类型?为什么新打开的文件的文件描述符不是从0开始? 文件描述符 fd (file descriptor) C语言的文件接口 当时学习C语言的时候,学习了文件接口 具体可以查看之前的文章: 链接:C语言的文…

flask库

文章目录 flask库1. 基本使用2. 路由路径和路由参数3. 请求跳转和请求参数4. 模板渲染1. 模板变量2. 过滤器3. 测试器 5. 钩子函数与响应对象 flask库 flask是python编写的轻量级框架&#xff0c;提供Werkzeug&#xff08;WSGI工具集&#xff09;和jinjia2&#xff08;渲染模板…

【PyTorch】基础学习:在Pycharm等IDE中打印或查看Pytorch版本信息

【PyTorch】基础学习&#xff1a;在Pycharm等IDE中打印或查看Pytorch版本信息 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…

机器硬件命令

一、查看机器核数 有以下几种方法 1、lscpu命令 lscpu命令可以显示关于CPU的信息&#xff0c;包括核数、线程数等。在终端中输入以下命令即可查看CPU核数&#xff1a;该命令会输出CPU每个物理插槽的核数。 lscpu | grep "Core(s) per socket" | awk {print $NF} …

C++中实现String类

String类实现 概述示例开发环境代码运行结果 注意 概述 本文主要记录自己实现一个String类中的部分功能。 示例 开发环境 Windows下Visual Studio 2019。 代码 MyString.h #pragma once #include <iostream>class MyString{ public:MyString();MyString(char *p);…

github登录时解决2FA问题

使用Edge浏览器下载插件 https://microsoftedge.microsoft.com/addons/detail/authenticator-2fa-client/ocglkepbibnalbgmbachknglpdipeoio 下载后弹框会显示是否添加&#xff0c;添加。如下&#xff1a; Chrome下 https://chrome.google.com/webstore/detail/authenticator…

景联文科技:提供通用多模态数据,助力AI多模态领域实现飞跃式发展

回顾2023年&#xff0c;以ChatGPT为代表的通用人工智能大模型在全球范围内掀起了新一轮人工智能产业发展浪潮&#xff0c;我国人工智能大模型市场呈现百“模”争鸣、日新月异的迅猛发展态势。 根据大模型之家、钛媒体数据&#xff0c;2023年中国大模型市场规模达到147亿人民币&…

Elasticsearch:从 Java High Level Rest Client 切换到新的 Java API Client

作者&#xff1a;David Pilato 我经常在讨论中看到与 Java API 客户端使用相关的问题。 为此&#xff0c;我在 2019 年启动了一个 GitHub 存储库&#xff0c;以提供一些实际有效的代码示例并回答社区提出的问题。 从那时起&#xff0c;高级 Rest 客户端 (High Level Rest Clie…

vizro,一个有趣的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个有趣的 Python 库 - vizro。 Github地址&#xff1a;https://github.com/mckinsey/vizro 在当今数据驱动的世界中&#xff0c;数据可视化扮演着至关重要的角色。它不仅可以…

西门子PLC常用底层逻辑块分享_电动蝶阀

文章目录 前言一、功能概述二、电动蝶阀程序编写1.创建自定义数据类型2.创建FB功能块“电动蝶阀”3.编写程序 前言 本文分享一个自己编写的电动蝶阀控制逻辑块。 一、功能概述 手动状态、自动状态、机旁状态、强制状态、检修状态自由切换&#xff1b;具有开阀超时、关阀超时报…

状态机高阶讲解-06

1069 00:45:36,160 --> 00:45:37,660 那下一个用途 1070 00:45:39,010 --> 00:45:43,830 就是为分割系统提供一些参考的证据了 1071 00:45:47,230 --> 00:45:49,470 现在很多那个 1072 00:45:49,880 --> 00:45:51,770 流行有微服务架构 1073 00:45:51,770 --&g…

MATLAB/SIMULINK流水账

01.模块大小的一致性 当模型建完以后&#xff0c;模型大小比较散乱&#xff0c;可以利用该功能快速整理模块的大小 例如&#xff1a;如下5个constant模块&#xff0c;大小不一 若想把所有的模块都调整至跟第3个模块一样的大小 需要先把5个模块全部选取起来&#xff0c;另外再…

数字多空策略(实盘+回测+数据)

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

3.15号arm

汇编语言 1. 汇编语言的组成 汇编文件中由伪操作、伪指令、汇编指令以及代码注释这几部分组成 伪操作&#xff1a; ARM的汇编中伪操作以.为前缀&#xff0c;所有的伪操作不占用内存空间&#xff0c;编译汇编时告诉编译器怎么编译当前文件&#xff0c;主要用来修改汇编内…

QT下跨平台库实现及移植经验分享

最近在移植公司一个QT桌面软件到android上&#xff0c;有一些公司自定义的库&#xff0c;用了很多windows的api&#xff0c;移植过程很是曲折&#xff0c;在此有一些感悟分享一下~ 一.自编写跨平台库 1.有时候为了程序给第三方用需要编译一些qt封装库&#xff0c;并可能跨平台…

【SQL Server】实验四 数据更新

1 实验目的 掌握SQL数据更新语句的基本使用方法&#xff0c;如UPDATE、DELETE、INSERT。掌握更新语句条件中的嵌套查询使用方法。 2 实验内容 2.1 掌握SQL更新语句的基本使用方法 INSERT基本语句。UPDATE基本语句。DELETE基本语句。 2.2 掌握SQL更新语句的高级使用方法 …

Soft Robotics 变结构手掌和变刚度手指的仿人软体手的人机交互操作-武科大ESIR课题组师兄成果

一、引言 在当今的机器人技术领域&#xff0c;人类对机器人的需求日益增长&#xff0c;涉及到工业生产、医疗护理、服务业等各个领域。然而&#xff0c;由于任务的多样性和复杂性&#xff0c;单独依靠自主机器人操作往往难以满足实际需求。为了解决这一问题&#xff0c;人机协作…

社交革命的引领者:探索Facebook如何改变我们的生活方式

1.数字社交的兴起 随着互联网的普及&#xff0c;社交媒体成为我们日常生活的重要组成部分。Facebook作为其中的先驱&#xff0c;从最初的社交网络演变成了一个拥有数十亿用户的全球化平台。它不仅改变了我们与世界互动的方式&#xff0c;还深刻影响了我们的社交习惯、人际关系以…