题目描述
输出示例
题解一
思路一
其实就是两个遍历,不停输出当前最小和最大,并且需要pop出来相对应的字符。
但其实代码实现起来,我感觉有点难度
代码一(附带讲解)
class Solution:
# 寻找下一个最小值(在从小到大遍历中用到),输入为当前值和当前列表,输出为下一个最小值和它的index
def find_next_min(self, formal_min, s:list):
min_num = max(s)
min_index = -1
for i in range(len(s)):
if (s[i]<=min_num and s[i]>formal_min):
min_num = s[i]
min_index = i
if min_index == -1:
for i in range(len(s)):
if (s[i]==formal_min):
min_num=s[i]
min_index=i
return min_num,min_index
# 寻找下一个最大值(在从大到小遍历中用到),输入为当前值和当前列表,输出为下一个最大值和它的index
def find_next_max(self, formal_max, s:list):
max_num = min(s)
max_index = -1
for i in range(len(s)):
if (s[i]>=max_num and s[i]<formal_max):
max_num = s[i]
max_index = i
if max_index == -1:
for i in range(len(s)):
if (s[i]==formal_max):
max_num = s[i]
max_index = i
return max_num,max_index
# 用来进行字符串重拍
def sortString(self, s: str) -> str:
ls = list(s)
new_str='' #用来返回的string
while(True):
if (len(ls) == 0):
break
# 当前最小值和最大值(字符串会变化),以及其index
now_min_num, min_index = min_num, pp = self.find_next_min('`', ls)
now_max_num, max_index = max_num, pp = self.find_next_max('{', ls)
#不断迭代从小往大遍历
while(min_num < now_max_num):
new_str += ls.pop(min_index)
min_num,min_index = self.find_next_min(min_num,ls)
now_max_num = max(ls)
new_str += ls.pop(min_index)
if (len(ls) == 0):
break
now_min_num, min_index = min_num, pp = self.find_next_min('`', ls)
now_max_num, max_index = max_num, pp = self.find_next_max('{', ls)
#不断迭代从大往小遍历
while(max_num > now_min_num):
new_str += max_num
ls.pop(max_index)
max_num,max_index = self.find_next_max(max_num,ls)
now_min_num = min(ls)
new_str += max_num
ls.pop(max_index)
return str(new_str)
运行结果
看到如此复杂迭代的代码,我就已经预知这个不太好了
题解二
思路二
既然题目中说所有字符均为小写字符, 那么我们可以先把所有的字符先都放在对应的“桶”里。然后不停往返遍历,到了终点,就从头再来一次,直到所有桶内所有字符都被取走
代码二
class Solution:
def fill_backet(self,backet,str):
for i in range(len(str)):
backet[ord(str[i]) - ord('a')] += 1
def check_empty(self,backet):
for i in range(0,26):
if backet[i] > 0 :
return False
return True
def traverse(self,new_str,backet):
i=0
difference = 1
while(True):
if (backet[i]>0):
new_str += chr(i + ord('a'))
backet[i] -= 1
i+=difference
#到达26 或 0
if (i == 26):
difference = -1
i+=difference
else:
if (i == -1):
difference = 1
i+=difference
if self.check_empty(backet):
return new_str
def sortString(self, s: str) -> str:
backet = [0] * 26
self.fill_backet(backet,s)
new_str = ""
new_str = self.traverse(new_str,backet)
return new_str
运行结果
用时从1.3k ms到了 124 ms,时间不到之前的0.1
虽然简化了不少,但是还是不够理想
代码改进
其实不必要每次都去check_empty,可以记录操作次数,一个长度为n的字符串操作次数应该是n
所以:
def traverse(self,new_str,backet,lenth):
i=0
difference = 1
operation_times = 0
while(True):
if (backet[i]>0):
new_str += chr(i + ord('a'))
operation_times+=1
backet[i] -= 1
i+=difference
#到达26 或 0
if (i == 26):
difference = -1
i+=difference
else:
if (i == -1):
difference = 1
i+=difference
if operation_times == lenth:
return new_str
很快啊,我们就获得了显著性的突破:
官方代码(十分简洁)
思路还是跟我的一样,不过大佬写出来的代码就是简洁
class Solution:
def sortString(self, s: str) -> str:
num = [0] * 26
for ch in s:
num[ord(ch) - ord('a')] += 1
ret = list()
while len(ret) < len(s):
for i in range(26):
if num[i]:
ret.append(chr(i + ord('a')))
num[i] -= 1
for i in range(25, -1, -1):
if num[i]:
ret.append(chr(i + ord('a')))
num[i] -= 1
return "".join(ret)
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/increasing-decreasing-string/solution/shang-sheng-xia-jiang-zi-fu-chuan-by-leetcode-solu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
显然,这个相比我的代码更加好,因为内存消耗高一些其实无所谓(硬件越来越发达),运行时间才是王道