leetcode:3. 无重复字符的最长子串
问题描述:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
解法:滑动窗口,元素如果不在字典里面,就右移右边界(扩大);元素在字典里面,就右移左边界(缩小)。通过右边界的指针循环遍历,直到右边界达到末尾。因为左边界最多比右边界在右边一位,因而不用规定左边界。
时间复杂度:O(1)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
l = 0
r = -1
dict1 = {}
res = 0
while r < len(s) - 1:
if dict1.get(s[r + 1], 0) == 0:
r += 1
dict1[s[r]] = 1
else:
dict1[s[l]] -= 1
l += 1
res = max(res, r-l+1)
return res
leetcode:125. 验证回文串
问题描述:给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
解法:双指针,str.isalnum() 方法-检测字符串是否由字母和数字组成。str.upper() 方法-字符串中的小写字母转为大写字母。
时间复杂度:O(n)
# 法一:双指针
class Solution:
def isPalindrome(self, s: str) -> bool:
s = [i for i in s.upper() if i.isalnum()]
l = 0
r = len(s) - 1
while l < r:
if s[l] != s[r]:
return False
else:
l += 1
r -= 1
return True
# 法二:直接比较字母翻转的字符串
class Solution:
def isPalindrome(self, s: str) -> bool:
s = [i for i in s.upper() if i.isalnum()]
return s == s[::-1]
剑指offer:替换空格
问题描述:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
解法:
1.先遍历一遍字符串,统计空格的总数。新的长度=原长度+空格数×2,准备两个指针,一个指向原始末尾,一个指向替换后的末尾,从后往前复制。
2.创建一个数组,先遍历一遍字符串,将元素分别放入数组,空格则放入替换字符,最后数组转为字符串 ''.join(a)
时间复杂度:O(n)
# -*- coding:utf-8 -*-
class Solution:
def replaceSpace(self, s):
# 字符串是不可变对象,不要用下标的方法去改变字符串的值
a = []
for i in range(len(s)):
if s[i] == ' ':
a.append('%20')
else:
a.append(s[i])
return ''.join(a)
leetcode:14. 最长公共前缀
问题描述:编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""
。
解法:
1. 把数组的第一位字符串看做标准位数循环遍历(pos),从第二位字符串开始循环遍历(_),如果扫描到的字符串长度小于等于当前位数,则标志为False;如果扫描的字符串位置不等于标准位置,则标志为False
2. zip(*strs)函数将列表变换成元组。然后使用集合set的互异性,判断set后的元组长度等于1,等于1则认为该字符是公共前缀,加入公共前缀字符串
时间复杂度:
# method 1
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
res = ''
flag = True
# pos : 位数
# _ : 第几个数
if strs == []:
return res
for pos in range(len(strs[0])):
for _ in range(1, len(strs)):
if len(strs[_]) <= pos:
flag = False
elif strs[0][pos] != strs[_][pos]:
flag = False
if flag:
res += strs[0][pos]
else:
break
return res
# method 2
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
res = ""
if len(strs) == 0:
return ""
# zip(*strs)函数的作用是将列表变换成元组
for each in zip(*strs):
# 集合set的互异性,set后的元组长度等于1则认为该字符是公共前缀,加入公共前缀字符串
if len(set(each)) == 1:
res += each[0]
else:
return res
return res
企业真题:在串”aaabbaa”中,S的子串为S中任意连续的一段。度度熊想找的子串有”a”,”aa”,”aaa”,”b”,”bb”五种,输出子串数目。
解法:两个指针,右边界扩张,左边界识别相同元素。
import sys
line = sys.stdin.readline().strip()
l = 0
r = -1
res = []
while r < len(line) - 1:
if line[l] == line[r+1]:
r += 1
else:
l += 1
if line[l:r + 1] not in res and r >= l:
res.append(line[l:r+1])
print(len(res))
leetcode:424. 替换后的最长重复字符
问题描述:给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
解法:用字典保存字母出现的次数,需要替换的字符数目=窗口字符数目-数量最多的字符数目
时间复杂度:O(n)
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
# 用字典保存字母出现的次数,需要替换的字符数目=窗口字符数目-数量最多的字符数目
letter_num = {}
l = 0
res = 0
for r in range(len(s)):
# 字典保存字符出现的次数
letter_num[s[r]] = letter_num.get(s[r], 0) + 1
# 找到出现次数最多的字符
max_letter = max(letter_num, key=letter_num.get)
# 如果替换的字符数目超过给定的k,则移动左边界
while r - l + 1 - letter_num[max_letter] > k:
letter_num[s[l]] -= 1
l += 1
# 需要更新最多个数的字符
max_letter = max(letter_num, key=letter_num.get)
# 如果s[r] 超出了替换的字符数目,需要先处理,再计算结果
res = max(res, r - l + 1)
return res
剑指offer:字符串的排列
问题描述:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba
解法:分别把第一个字符与其后的所有字符依次做交换,然后固定第一个字符,递归地求后面字符的排列
时间复杂度:O(n*n)
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.res = []
def Permutation(self, ss):
if not ss:
return []
# python 不可直接修改string,转换为数组进行处理
self.Permutation_s(list(ss), 0)
# 去重
res = list(set(self.res))
# 排序
res.sort()
return res
def Permutation_s(self, char, start):
# 递归到最后一位字符
if start == len(char):
self.res.append(''.join(char))
# 首位start依次与其后的字符交换位置
for i in range(start, len(char)):
char[start], char[i] = char[i], char[start]
# 固定首位,递归余下的字符
self.Permutation_s(char, start + 1)
# 复原之前的顺序
char[start], char[i] = char[i], char[start]
剑指offer:第一个只出现一次的字符
问题描述:在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
解法:建立一个哈希表(字典)
时间复杂度:O(n)
# -*- coding:utf-8 -*-
class Solution:
def FirstNotRepeatingChar(self, s):
if not s:
return -1
dict1 = {}
for i in s:
dict1[i] = dict1.get(i, 0) + 1
for i in range(len(s)):
if dict1[s[i]] == 1:
return i
剑指offer:
问题描述:
解法:
时间复杂度: