给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2 输出:"bacd"
提示:
1 <= s.length <= 104
s
仅由小写英文组成1 <= k <= 104
思路一:这道题直观的解决思路就是按照题意进行模拟。在思维上没有太多困难的题那就比较考察代码编写了,这里主要考察对字符串的反转操作,提到字符串,就不可能不提到它的切片操作,有关字符串的切片,可以看看下面的这篇博客。
在这里用到的S[i:i+k]也就是取s中下标为i到i+k的字符,其中不包括第i+k个字符;
s[a:b:-1]表示对字符串s从索引a到索引b(不包含b)进行倒序操作,了解了这个知识点,我们就可以很容易地完成对字符串的反转了。
字符串切片详解:【python基础】python切片—如何理解[-1:],[:-1],[::-1]的用法_python[-1:]-CSDN博客
代码(Python):
class Solution(object):
def reverseStr(self, s, k):
result = ''
for i in range(0,len(s),2*k): #遍历s,步长为2k
if i+2*k<=len(s): #若有2k个字符,可以反转
result += s[i:i+k][::-1] #反转前k个
result += s[i+k:i+2*k] #k+1到2k个不变
elif len(s) - i <k: #若剩余的不足k个
result += s[i:len(s)][::-1] #则反转剩余的全部字符
break;
elif len(s) - i >= k and len(s) - i <2*k: #若剩余的大于K个小于2k个
result += s[i:i+k][::-1] #反转前K个
result += s[i+k:len(s)] #剩余的不变
break;
return result
思路二:思路一就是很常规的根据题意进行模拟,但我在翻看题解的时候又发现了一种很好的解法,在这里也记录一下。
题目给的是每2k个字符,就要进行相应的操作,所以我们的思路是每2k个字符要进行一下操作,把步长设置为了2k;但仔细观察可以发现,每2k个字符,对前k个字符反转,对后k个字符不反转,事实上就是每k个字符进行一次操作,只不过操作的内容不一样罢了,因此我们可以设置一个标识符flag,遍历s的步长设置为k,在奇数次k的时候进行反转,而偶数次k的时候不反转。
这时候再来看题目的条件:
- 每计数至
2k
个字符,就反转这2k
字符中的前k
个字符。- 如果剩余字符少于
k
个,则将剩余字符全部反转。- 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。第一个条件满足,因为我们就是这么设计的思路;第二个条件,剩余的字符数量是相对于前面已经进行了一次2k字符的操作来说的,若不足k个,说明在2k字符里,它属于前k个字符那一段,因此一定是奇数次k,故会进行反转,满足;第三个条件,也就是说对于2段字符,第一段长度为k,第二段长度不足k,第一段也就是奇数次k要反转,第二段也就是偶数次k不进行反转,也满足。因此就把题目简化成对奇数次/偶数次k个字符的处理了,不得不佩服大佬的思路。
代码(Python):
class Solution(object):
def reverseStr(self, s, k):
result = ''
flag = True
for i in range(0,len(s),k): #遍历s,步长为k
if flag: #奇数次k反转
result += s[i:i+k][::-1]
else: #偶数次不反转
result += s[i:i+k]
flag = not flag
return result