ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

演练:字符串中的反转元音

2022-09-09 13:30:57  阅读:259  来源: 互联网

标签:word 迭代 字符串 length 元音 堆栈 演练


演练:字符串中的反转元音

朋友们好,这是 Saadin 告诉你我如何解决 LeetCode 中的一个问题。让我们直接潜入。废话,我们走吧。

问题

给定一个字符串 s ,仅反转字符串中的所有元音并返回它。

元音是 '一个' , 'e' , '一世' , 'o' , 和 “你” ,并且它们可以出现在这两种情况下。

在这个例子中,如果我把单词“hello”作为我的字符串,我的方法必须返回字符串“holle”。

忘记 1 和 0

Photo by 亚伦负担 on 不飞溅

好的,所以首先,让我们暂时放下电脑谈话。我从 Gayle Laakmann McDowell 的 破解编码面试。 如果我告诉一个中学生实施二分搜索,他们要么当场放弃,要么他们的小脑袋可能会爆炸,除非我在和我说话 马尔科姆·威尔克森 .

但是,如果我告诉他们拿一本字典并在其中找到“quest”这个词,你可以很确定他们会做类似二进制搜索的事情:他们会知道“q”比“z”更接近它是'a',所以他们会走到书的结尾。也许那时他们会按“v”,所以他们会开始翻页。然后他们会向后翻转并按“p”。又太远了。最后,他们会按“q”并找到 quest 这个词。

上述过程是合乎逻辑的,其概念类似于二分查找。不要迷失在我们正在制作算法的事实中。想想现实世界的解决方案是什么。我可能仍然会使用蛮力,但我的蛮力会稍微聪明一些。

就我而言,我只想翻转元音,所以我将左右食指指向弦的两端;一个在索引 0 处,然后一个在索引 n-1 处,其中 n 是字符串中的字符数。

我想把我的手指越来越近,一个字母一个字母地走。如果我用一根手指敲击元音,我会停下来;当我在另一根手指上敲击元音时,我翻转它们,然后继续我的过程。

酷,让我们把这个概念带到计算机上。

蛮力

诚然,我以前没有见过这个问题,所以我会尝试实施我的解决方案,这可能会变得混乱。但它会做。

首先,我们将字符串转换成一个字符数组,称为 单词 因为字符串是不可变的,因此使用起来有点烦人。

然后我们用两个变量设置了一个while循环。一个会去 s.length()-1 - AKA 最后一个索引 - 另一个将从索引 0 开始。循环结束时 一世 大于 j .这是我最初提出的完整解决方案:

 公共字符串反向元音(字符串 s){  
 char[] word = new char[s.length()];  
 for (int i = 0; i < s.length(); i++) {  
 字[i] = s.charAt(i);  
 }  
          
 诠释 i = 0;  
 int j = s.length() - 1;  
 堆<Integer>iq = 新堆栈<Integer>();  
 堆<Integer>jq = 新堆栈<Integer>();  
          
 而 (i < j) {  
 if (/*检查 word[i] 是否为元音*/) {  
 iq.add(i);  
 }  
 if (/*检查 word[j] 是否是元音*/) {  
 jq.add(j);  
 }  
              
 if (!iq.isEmpty() && !jq.isEmpty()) {  
 //我们找到了必须交换的两个元音!翻转它们!  
 iq.pop();  
 char tempC = word[i];  
 jq.pop();  
 词[i] = 词[j];  
 词[j] = tempC;  
 }  
              
 if (iq.isEmpty()) i++;  
 if (jq.isEmpty()) j--;  
 }  
 返回新字符串(单词);  
 }

起初,我以为我会继续迭代,然后记下索引,以便在变量不断迭代的同时进行交换。这没有帮助,但我并没有摆脱堆栈的想法。我保留它以检查我的变量是否必须迭代(稍后会详细介绍)。

当我迭代时,我检查是否 词[j] 或者 词[我] 其中有元音。如果他们这样做,我将索引压入堆栈。

两个堆栈都有东西吗?太好了,我们交换了 一世 j .如果变量对应的栈为空,则迭代。如果没有,不要。

磨练算法

好吧,是时候问什么会更好了。

什么工作被做了两次?不管你多么聪明,你都会犯错,所以问自己这些问题很重要。我认为我通常很擅长解决算法问题,但我肯定注意到我的代码有些地方不太好。

我的筹码只有一个值;最重要的是,它们的一个值始终等于它们对应的值 一世 或者 j 多变的。我正在存储我不需要的信息。所以我用一种原始的、更轻的数据类型替换了堆栈:布尔值。我做一个 移动 __ 和 移动 __ 变量,我将这两个都设置为true。如果我的性格在 j 或者 一世 是元音,我将相应的布尔值设为假。如果 移动 是真的,我们迭代 一世 .如果 移动 是真的,我们迭代 j .这将使我的算法的空间复杂度好一点。这是完整的解决方案:

 类解决方案{  
 公共字符串反向元音(字符串 s){  
 char[] word = new char[s.length()];  
 for (int i = 0; i < s.length(); i++) {  
 字[i] = s.charAt(i);  
 }  
          
 诠释 i = 0;  
 int j = s.length() - 1;  
 布尔 iMove = true;  
 布尔 jMove = true;  
 堆<Integer>jq = 新堆栈<Integer>();  
          
 而 (i < j) {  
 if (/*检查 word[i] 是否为元音*/) {  
 iMove = 假;  
 }  
 if (/*检查 word[j] 是否是元音*/) {  
 jMove = 假;  
 }  
              
 如果 (!iMove && !jMove) {  
 //我们找到了必须交换的两个元音!翻转它们!  
 char tempC = word[i];  
 词[i] = 词[j];  
 词[j] = tempC;  
 iMove =真;  
 jMove =真;  
 }  
              
 如果 (iMove) i++;  
 如果 (jMove) j--;  
 }  
 返回新字符串(单词);  
 }  
 }

最坏的输入场景是一串字符,最后只有两个元音。该算法将运行 n-2 个条目,因此我们的大 O 时间是 O(n-2),可以简化为 O(n)。

包起来

你怎么知道你已经完成了,没有办法变得更好?好吧,让我们想想我们在做什么。

我们缺乏关于元音在哪里或字符串包含多少元音的信息,所以我们绝对必须找出每个字符是什么,这意味着我们必须遍历 n 个字符。即使在理论上,我们最好的情况下运行时间也是 O(n)。我的算法是 O(n),所以我们开始了!如果不是当然,那意味着我可以以某种方式做得更好。幸运的是,这对我来说不是这样。

祝大家编码愉快!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/23048/22130913

标签:word,迭代,字符串,length,元音,堆栈,演练
来源: https://www.cnblogs.com/amboke/p/16672522.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有