开源地址
https://github.com/datawhalechina/leetcode-notes/blob/main/docs/ch07/index.md
最长子串的定义
最长 不重复的字串。
这个问题是一个经典的滑动窗口问题,可以通过维护一个窗口来解决,这个窗口内的字符都是唯一的。随着遍历字符串,窗口的右边界不断向右移动,如果遇到了一个新字符(即这个字符在当前窗口内没有出现过),则可以扩大这个窗口的右边界。如果遇到的这个新字符在窗口中已经存在了,那么就需要移动窗口的左边界,直到这个重复的字符被移出窗口。在这个过程中,记录下所遇到的最大窗口长度,这个长度就是题目所要求的最长无重复字符子串的长度
滑动窗口示例代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:return 0
left = 0
lookup = set()
n = len(s)
max_len = 0
cur_len = 0
for i in range(n):
cur_len += 1
while s[i] in lookup:
lookup.remove(s[left])
left += 1
cur_len -= 1
if cur_len > max_len:max_len = cur_len
lookup.add(s[i])
return max_len
使用字典维护字母出现的最后位置
def find_longest_substring(s):
# 's' 是输入的字符串
a = 0
b = 0
l = 0 # 'l' 用于记录最长的不重复子串的长度
char_index_map = {} # 用于记录字符最后出现的位置
# 遍历字符串
while b < len(s):
if s[b] not in char_index_map or char_index_map[s[b]] < a:
# 如果字符在窗口内没有重复,则更新字符的最新位置,并扩大窗口的右边界
char_index_map[s[b]] = b
b += 1
else:
# 如果字符在窗口内有重复,则缩小窗口的左边界,直到没有重复的字符为止
a = char_index_map[s[b]] + 1
# 在每一步中,都检查当前的不重复子串长度,并更新最长长度
l = max(l, b - a)
return l
字符串相加 相乘
字符串相加 相乘
字符串相加和相乘是两种常见的对数字进行操作的算法,特别是在数字超出标准数据类型范围或者需要精确表示大数时。这些操作的原理紧密模仿了我们从小在纸上进行加法和乘法的方法,只不过这里使用的是字符串来表示数字。下面是对这两种操作原理的总结:
字符串相加原理
- 逐位相加:从字符串表示的两个数字的最低位(即字符串的最右端)开始,逐位进行相加。如果其中一个数字较短,在任何缺少的位上假设其值为0。
- 处理进位:在每一步的加法中,如果相加的结果大于或等于10,则需要将进位(即结果的十位数)加到下一位的计算中。
- 反转结果(如果是从最高位开始加的话):在某些实现中,为了方便从最高位开始加,最后需要将结果反转。但在从低位开始加的实现中,这一步不是必需的。
- 拼接最终结果:将所有的计算结果拼接起来,形成最终的字符串表示。
字符串相乘原理
- 逐位乘法:将乘数的每一位(从最低位到最高位)与另一个乘数的每一位相乘。这相当于手工乘法中的“每位乘以整个数”,然后将所有结果按正确的位对齐。
- 位对齐:在乘法过程中,每一轮的乘法结果需要根据当前乘数位的位置进行位对齐(即移位)。例如,乘数的第二位与另一乘数相乘的结果需要左移一位(即乘以10)。
- 累加所有乘积:将所有的乘积结果累加起来,这一步需要处理进位。
- 处理进位:与加法类似,乘法的每一步都可能产生进位,需要将进位加到下一位的累加中。
- 最终结果:所有的中间乘积累加后,形成了最终的乘积结果。
字符串相加
def stradd(a,b):
# 初始化设计
c = ''
la,lb = len(a),len(b)
ml = max(la,lb)
jin = 0
for i in range(ml):
# 取得位数上的值
na = int(a[-1-i]) if i < la else 0
nb = int(b[-1-i]) if i < lb else 0
res = na + nb + jin
jin = res // 10 # 进位
c = str(res % 10) + c #累计计算值
if jin > 0: # 最后处理进位
c = str(jin) + c
return c
字符串相乘
def strmult(a,b):
# 初始化 长度 乘数列表
la,lb = len(a),len(b)
multi_res = [0] * (la+lb)
# 遍历所有的乘数1 乘数2的位数
for i in range(la-1, -1, -1):
for j in range(lb-1, -1, -1):
# 对于乘数2的每一位都乘 乘数1的每一位
res = int(a[i]) * int(b[j]) + multi_res[i+j+1]
multi_res[i+j] += res // 10
multi_res[i+j+1] = res % 10
# 把结果放到一个列表的位数上去
return ''.join(map(str,multi_res)).lstrip('0')
句子倒序
s ='i ame leech' # -> string
s = ' '.join(s.split()[::-1])
print(s)
最长公共前缀
def longest_prefix(strs):
# 找到最短的字符串
ml = min(len(s) for s in strs)
flag = 0
# 定义flags
for i in range(ml):
if all((s[i] == strs[0][i] for s in strs)): # 相等
flag += 1
else:
break
# 根据flags 返回结果
if flag:
return strs[0][:flag]
else:
return ''
print(longest_prefix(['flse','flors','flosre']))