2024-03-13
Go & Python & 算法
00

目录

1 LeetCode344 反转字符串
2 LeetCode541 反转字符串 Ⅱ
3 卡码网54 替换数字
4 LeetCode151 反转字符串中的单词
5 卡码网55 右旋字符串

今日任务:

  1. LeetCode344 反转字符串
  2. LeetCode541 反转字符串 Ⅱ
  3. 卡码网54 替换数字
  4. LeetCode151 反转字符串中的单词
  5. 卡码网55 右旋字符串

今日心情:在先翻转全部,然后翻转部分这个思路上踩了两次坑,这个要记住。

资料来源:

  1. 代码随想录 | LeetCode344 反转字符串
  2. 代码随想录 | LeetCode541 反转字符串 Ⅱ
  3. 代码随想录 | 卡码网54 替换数字
  4. 代码随想录 | LeetCode151 反转字符串中的单词
  5. 代码随想录 | 卡码网55 右旋字符串

1 LeetCode344 反转字符串

题目

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"] 输出:["h","a","n","n","a","H"]

提示:

  • 1 <= s.length <= 105
  • s[i] 都是 ASCII 码表中的可打印字符

大体思路就是前后两个指针,从头尾往中间去,一边走一边交换,这说是双指针我觉得也行。

另外就是文档里写到的:如果题目的关键部分用了库函数就能解决,那么就不要用库函数;如果库函数只是这个题目考察重点的一部分,且已经了解库函数的实现原理,那么可以使用库函数。

python
class Solution: def reverseString(self, s: List[str]) -> None: """ Do not return anything, modify s in-place instead. """ first, last, temp = 0, len(s) - 1, 0 while first < last: temp = s[first] s[first] = s[last] s[last] = temp first += 1 last -= 1

2 LeetCode541 反转字符串 Ⅱ

题目

给定一个字符串 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

大体思路就是先计算要翻转的次数,按照次数进行翻转。翻转完成后,如果剩下的是k到2k的部分,就不处理直接加入数组;如果是0到k的部分,就翻转。

踩坑:

image.png

另外注意代码里的列表转字符串写法:''.join(list)

python
# 我的代码 class Solution: def reverseStr(self, s: str, k: int) -> str: return_str = [] reverse_count = int(len(s) / k) if reverse_count % 2 == 0: reverse_count = int(reverse_count / 2) else: reverse_count = int(reverse_count / 2) + 1 print(reverse_count) pointer = -1 for _ in range(reverse_count): pointer += k for i in range(k): return_str.append(s[pointer - i]) for i in range(k): if pointer + i + 1 < len(s): return_str.append(s[pointer + i + 1]) pointer += k if pointer < len(s): for i in range(len(s) - pointer - 1): return_str.append(s[len(s) - 1 - i]) return ''.join(return_str)

3 卡码网54 替换数字

题目

题目描述

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入描述

输入一个字符串 s,s 仅包含小写字母和数字字符。

输出描述

打印一个新的字符串,其中每个数字字符都被替换为了number

输入示例

a1b2c3

输出示例

anumberbnumbercnumber

提示信息

数据范围: 1 <= s.length < 10000。

提示

一点小技巧:大多数数组填充类的题,可以先扩充数组到目标长度,然后从最后往前开始填充试试。

先遍历所有字符,找到数字,计算扩充后应有的长度,然后扩展数组,并且按从后往前的顺序开始从字符串的最后填充到数组的最后。

python
a = input() first_pointer = len(a) - 1 str_list = list(a) more_number_len = 0 for i in a: if 48 <= ord(i) <= 57: more_number_len += 5 str_list += ['0'] * more_number_len last_pointer = len(str_list) - 1 for first_pointer in range(first_pointer, -1, -1): if 48 <= ord(str_list[first_pointer]) <= 57: str_list[last_pointer] = "r" last_pointer -= 1 str_list[last_pointer] = "e" last_pointer -= 1 str_list[last_pointer] = "b" last_pointer -= 1 str_list[last_pointer] = "m" last_pointer -= 1 str_list[last_pointer] = "u" last_pointer -= 1 str_list[last_pointer] = "n" last_pointer -= 1 else: str_list[last_pointer] = str_list[first_pointer] last_pointer -= 1 print("".join(str_list))

4 LeetCode151 反转字符串中的单词

题目

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 1:

输入:s = "the sky is blue" 输出:"blue is sky the"

示例 2:

输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。

示例 3:

输入:s = "a good example" 输出:"example good a" 解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

提示:

  • 1 <= s.length <= 104
  • s 包含英文大小写字母、数字和空格 ' '
  • s 中 至少存在一个 单词

删空格部分不提,大致的思路就是先翻转所有的字符,然后按照单词一个一个翻转,就能把单词顺序翻转的同时,不改变单词内字符的顺序。

只是,在删空格部分被爆杀。

python
class Solution: def reverseWords(self, s: str) -> str: str_list = list(s) i = 0 while True: i += 1 if i >= len(str_list): # 因为是边查边删 for容易越界 break if ord(str_list[i]) == 32: if ord(str_list[i - 1]) != 32: # 单词之后的一个空格可以留 continue str_list.pop(i) i -= 1 if ord(str_list[0]) == 32: # 检查开头 str_list.pop(0) if ord(str_list[len(str_list) - 1]) == 32: # 检查结尾 str_list.pop(len(str_list) - 1) first_pointer = 0 last_pointer = len(str_list) - 1 while first_pointer < last_pointer: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp first_pointer += 1 last_pointer -= 1 first_pointer, last_pointer = 0, 0 while first_pointer < len(str_list) - 1: # 先让后指针找到要翻转的词的末尾 for last_pointer in range(last_pointer, len(str_list)): if last_pointer == len(str_list) - 1: break if ord(str_list[last_pointer]) == 32: last_pointer -= 1 break temp2 = last_pointer # 翻转词 while first_pointer < last_pointer: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp first_pointer += 1 last_pointer -= 1 # 再找到下一个词 if temp2 == len(str_list) - 1: first_pointer = temp2 else: first_pointer = temp2 + 2 last_pointer = temp2 + 2 return "".join(str_list)

5 卡码网55 右旋字符串

题目

题目描述 字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。

例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。

输入描述

输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出描述

输出共一行,为进行了右旋转操作后的字符串。

输入示例

2

abcdefg

输出示例

fgabcde

提示信息 数据范围:

  • 1 <= k < 10000,
  • 1 <= s.length < 10000;

属于是刷过前几题之后应该想到的,失算了,然后在错误的思路上狂奔。我的思路还是太过欠考虑,最后还是没做出来。实际上正确的解法和LeetCode151是一致的,先翻转所有,再按段翻转。

另,该思路也可活用于左旋,道理是差不多的。

python
# 我的代码 num = int(input()) str_list = list(input()) sub_num = len(str_list) - num first_pointer, last_pointer = 0, 0 if sub_num >= num: first_pointer = len(str_list) - 1 last_pointer = sub_num - 1 while first_pointer > 0: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp print(str_list) if last_pointer > 0: last_pointer -= 1 elif last_pointer == 0 and sub_num == num: break first_pointer -= 1 elif sub_num < num: first_pointer = sub_num last_pointer = 0 while last_pointer != len(str_list) - 1: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp if first_pointer < len(str_list) - 1: first_pointer += 1 last_pointer += 1 print("".join(str_list))
python
num = int(input()) str_list = list(input()) first_pointer = 0 last_pointer = len(str_list) - 1 while first_pointer < last_pointer: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp first_pointer += 1 last_pointer -= 1 first_pointer = 0 last_pointer = num - 1 while first_pointer < last_pointer: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp first_pointer += 1 last_pointer -= 1 first_pointer = num last_pointer = len(str_list) - 1 while first_pointer < last_pointer: temp = str_list[first_pointer] str_list[first_pointer] = str_list[last_pointer] str_list[last_pointer] = temp first_pointer += 1 last_pointer -= 1 print("".join(str_list))

本文作者:御坂19327号

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!