尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

数据结构与算法之字符串: LeetCode 557. 反转字符串中的单词 III (Ts, Py, Go, Java版)

数据结构与算法之字符串: LeetCode 557. 反转字符串中的单词 III (Ts, Py, Go, Java版) 翻转字符串中的单词 IIIhttps://leetcode.cn/problems/reverse-words-in-a-string-iii/描述给定一个字符串 s 你需要反转字符串中每个单词的字符顺序同时仍保留空格和单词的初始顺序。示例 1输入s Lets take LeetCode contest 输出steL ekat edoCteeL tsetnoc示例 2:输入 s God Ding 输出doG gniD提示1 s.length 5 *10410^4104s 包含可打印的 ASCII 字符。s 不包含任何开头或结尾空格。s 里 至少 有一个词。s 中的所有单词都用一个空格隔开。Typescript 版算法实现1 方案1functionreverseWords(s:string):string{returns.length?(s.match(/[\S]/g)??[]).map((item:string){returnitem.split().reverse().join()}).join( ):};console.log(reverseWords(Lets take LeetCode contest));不太推荐正则在算法中使用2 方案2functionreverseWords2(s:string):string{if(!s.length)returnreturns.split( ).map((item:string){returnitem.split().reverse().join()}).join( )}console.log(reverseWords2(Lets take LeetCode contest));推荐3 方案3functionreverseWords3(s:string):string{if(!s.length)returnreturns.split(/\s/g).map((item:string){returnitem.split().reverse().join()}).join( )}console.log(reverseWords3(Lets take LeetCode contest))// blue is sky the不太推荐正则在算法中使用可通过4 ) 方案4functionreverseWords4(s:string):string{if(!s.length)returnreturn(s.match(/[\w]/g)??[]).map((item:string){returnitem.split().reverse().join()}).join( )}console.log(reverseWords4(Lets take LeetCode contest))不太推荐正则在算法中使用这个算法有问题的部分 case 无法通过注意这里的方案4是有问题的能满足示例字符串但是满足不了一些特殊字符串有一些英语句子中可以加一些特指字符比如 $, \ 等语法和写法上会有区别最简单的来说 , .等字符都没有囊括在内如果非要用 \w 并手动加符号呢理论上可以写成字符集比如 [\w(),]但你必须穷举所有可能出现的符号这既不现实也不优雅。所以 直接换用 \S 或 split(’ ) 才是正确的选择。5 方案5functionreverseWords5(s:string):string{constwordss.split( );for(leti0;iwords.length;i){words[i]reverseWord(words[i]);}returnwords.join( );}functionreverseWord(word:string):string{letcharsword.split();letleft0;letrightchars.length-1;while(leftright){[chars[left],chars[right]][chars[right],chars[left]];left;right--;}returnchars.join();}console.log(reverseWords5(Lets take LeetCode contest));上述是使用双指针的方式来转换这种实际上性能并不高从算法结构上来看就不是很高字符串被切分进行交换没有方案2好用来扩展思路相关apiconst{split,match}String.prototypeconst{map,reverse,join}Array.prototype总结注意边界非空判断将字符串转换成数组这里是一维数组在数组内的每个字符串元素转换成数组这里是第二维数组在单个字符串数组元素借助reverse这个api进行反转将单个字符串数组元素再次转换成字符串元素将处理好二维数组元素转换好的字符串在一维数组内作为元素返回注意使用for循环来做反而麻烦代码量大尽量不用Python3 版算法实现1 简洁版本classSolution:defreverseWords(self,s):return .join(word[::-1]forwordins.split( ))2 使用 enumerateclassSolution:defreverseWords(self,s:str)-str:lts.split()# 使用 enumerate 将数组转换成 枚举结构fori,winenumerate(lt):lt[i]w[::-1]# 单位内反转return .join(lt)# 转换成字符串Golang 版算法实现1 字符串和数组的组合funcreverseWords(sstring)string{// 拆分数组words:strings.Split(s, )// 倒序输出fori:0;ilen(words);i{words[i]reverse(words[i])}// 最终结果returnstrings.Join(words, )}// 对字符串进行反转funcreverse(wordstring)string{// 转成数组ans:[]byte(word)// 获取前后索引l,r:0,len(ans)-1// 前后翻转forlr{ans[l],ans[r]ans[r],ans[l]lr--}// 获取结果returnstring(ans)}Java 版算法实现1 ) 正则匹配与拼接importjava.util.ArrayList;importjava.util.List;importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassMain1{publicstaticStringreverseWords(Strings){if(s.isEmpty()){return;}PatternpatternPattern.compile([\\S]);Matchermatcherpattern.matcher(s);ListStringreversedWordsnewArrayList();while(matcher.find()){Stringwordmatcher.group();reversedWords.add(newStringBuilder(word).reverse().toString());}returnString.join( ,reversedWords);}publicstaticvoidmain(String[]args){System.out.println(reverseWords(Lets take LeetCode contest));}}算法说明正则提取使用正则表达式[\S]匹配并提取字符串中所有由非空字符组成的单词。逐个反转遍历匹配到的单词利用StringBuilder的reverse()方法对每个单词进行反转。重新拼接将反转后的单词存入列表最后使用空格作为分隔符将所有单词重新拼接成完整的字符串。2 ) 字符串分割与拼接 (String Splitting and Concatenation)publicclassMain2{publicstaticStringreverseWords2(Strings){if(s.isEmpty()){return;}String[]wordss.split( );StringBuilderresultnewStringBuilder();for(inti0;iwords.length;i){result.append(newStringBuilder(words[i]).reverse().toString());if(iwords.length-1){result.append( );}}returnresult.toString();}publicstaticvoidmain(String[]args){System.out.println(reverseWords2(Lets take LeetCode contest));}}算法说明字符串分割使用split( )方法按空格将原字符串分割成单词数组。逐个反转遍历单词数组利用StringBuilder的reverse()方法对每个单词进行反转。重新拼接将反转后的单词依次追加到结果StringBuilder中并在单词之间手动添加空格分隔符最后返回拼接好的完整字符串。3 ) 空白分割与过滤拼接 (Whitespace Splitting and Filtered Concatenation)publicclassMain3{publicstaticStringreverseWords(Strings){if(s.isEmpty()){return;}String[]wordss.split(\\s);StringBuilderresultnewStringBuilder();for(inti0;iwords.length;i){if(!words[i].isEmpty()){result.append(newStringBuilder(words[i]).reverse().toString());if(iwords.length-1){result.append( );}}}returnresult.toString();}publicstaticvoidmain(String[]args){System.out.println(reverseWords(Lets take LeetCode contest));}}算法说明空白分割使用正则表达式\\s按空白字符将原字符串分割成数组。过滤空串遍历数组时跳过因连续空格产生的空字符串仅处理有效单词。反转与拼接利用StringBuilder反转有效单词将其追加到结果中并在单词之间手动添加空格分隔符最后返回完整字符串。4 ) 正则匹配与拼接 (Regex Matching and Concatenation)importjava.util.ArrayList;importjava.util.List;importjava.util.regex.Matcher;importjava.util.regex.Pattern;classSolution{publicStringreverseWords(Strings){if(s.isEmpty()){return;}// Pattern pattern Pattern.compile([\\w]); // 存在错误PatternpatternPattern.compile(\\S);// 可通过Matchermatcherpattern.matcher(s);ListStringreversedWordsnewArrayList();while(matcher.find()){Stringwordmatcher.group();reversedWords.add(newStringBuilder(word).reverse().toString());}returnString.join( ,reversedWords);}}算法策略名称算法说明正则提取使用正则表达式\S匹配并提取字符串中所有由非空格字符组成的单词。逐个反转遍历匹配到的单词利用StringBuilder的reverse()方法对每个单词进行反转。重新拼接将反转后的单词存入列表最后使用空格作为分隔符将所有单词重新拼接成完整的字符串。这个就是 策略 1 对照不可用的 正则5 ) 分割与双指针反转 (Splitting and Two-Pointer Reversal)publicclassMain5{publicstaticStringreverseWords(Strings){String[]wordss.split( );for(inti0;iwords.length;i){words[i]reverseWord(words[i]);}returnString.join( ,words);}publicstaticStringreverseWord(Stringword){char[]charsword.toCharArray();intleft0;intrightchars.length-1;while(leftright){chartempchars[left];chars[left]chars[right];chars[right]temp;left;right--;}returnnewString(chars);}publicstaticvoidmain(String[]args){System.out.println(reverseWords(Lets take LeetCode contest));}}算法说明字符串分割使用split( )方法按空格将原字符串分割成单词数组。双指针反转遍历单词数组对每个单词使用左右双指针向中间靠拢的方式交换字符实现反转。重新拼接使用String.join方法将反转后的单词数组用空格重新拼接成完整的字符串。
返回列表