3. 无重复字符的最长子串
难度:中等
题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
def longestSubStr(s):
ans=''
t=''
for i in s:
if i not in t:
t+=i
else:
t=t[(t.index(i)+1):]
t+=i
if(len(ans)<len(t)):
ans=t
return len(ans)
5. 最长回文子串
难度:中等
题目描述
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
'''
以i为中心,向两边扩展
'''
def longestPalindrome(s):
def expandI(l,r):
while(l>=0 and r<len(s) and s[l]==s[r]):
l-=1
r+=1
return l+1,r-1
r_s,r_e=0,-1
for i in range(len(s)):
l1,r1=expandI(i,i)
l2,r2=expandI(i,i+1)
if(r1-l1)>(r_e-r_s):
r_s,r_e=l1,r1
if(r2-l2)>(r_e-r_s):
r_s,r_e=l2,r2
print(r_s,r_e)
return s[r_s:r_e+1]
6. Z 字形变换
难度:中等
题目描述
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
'''
1、申明nrow的数组,逐次增加字符
2、i记录行号,flag记录向上还是向下移动
3、合并每行
'''
def zConvert(s,n):
if n<2:
return s
r=['' for i in range(n)]
i,flag=0,-1
for c in s:
r[i]+=c
if i==0 or i==n-1:
flag=-flag
i+=flag
return ''.join(r)
难度简单
给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
注意:整数序列中的每一项将表示为一个字符串。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
第一项是数字 1
描述前一项,这个数是 1
即 “一个 1 ”,记作 11
描述前一项,这个数是 11
即 “两个 1 ” ,记作 21
描述前一项,这个数是 21
即 “一个 2 一个 1 ” ,记作 1211
描述前一项,这个数是 1211
即 “一个 1 一个 2 两个 1 ” ,记作 111221
示例 1:
输入: 1
输出: "1"
解释:这是一个基本样例。
示例 2:
输入: 4
输出: "1211"
解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。
'''
1、两个变量pre,cur;pre记录上一个数字的表示,cur记录当前数字的表示
2、start,end指针计数
3、当前cur更新
'''
def countAndShow(n):
pre=''
cur='1'
for i in range(1,n):
pre=cur
cur=''
s,e=0,0
while(e<len(pre)):
while(e<len(pre) and pre[s]==pre[e]):
e+=1
cur+=str(e-s)+pre[s]
s=e
return cur
49. 字母异位词分组
难度:
中等
题目描述
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
'''
将列表中的字符串转化为排序字符;根据排序字符进行归类
'''
def groupGrams(s):
r={}
for c in s:
k=''.join(sorted(list(c)))
if k not in r.keys():
r[k]=[c]
else:
r[k].append(c)
return r.values()
难度中等
给定一个字符串,逐个翻转字符串中的每个单词。
说明:
- 无空格字符构成一个 单词 。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
示例 1:
输入:"the sky is blue
" 输出:"blue is sky the
"
示例 2:
输入:" hello world! "
输出:"world! hello"
解释:输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入:"a good example"
输出:"example good a"
解释:如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
'''
1、使用split分割,反转
2、空格拼接
'''
def reverse(s):
r=' '.join([c for c in s.split()[::-1]])
return r
165. 比较版本号
难度:中等
题目描述
比较两个版本号 version1 和 version2。 如果 version1 > version2
返回 1,如果 version1 < version2
返回 -1, 除此之外返回 0。
你可以假设版本字符串非空,并且只包含数字和 .
字符。
.
字符不代表小数点,而是用于分隔数字序列。
例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。
你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 3 和 4。其第三级和第四级修订号均为 0。
示例 1:
输入: version1 = "0.1", version2 = "1.1"
输出: -1
示例 2:
输入: version1 = "1.0.1", version2 = "1"
输出: 1
示例 3:
输入: version1 = "7.5.2.4", version2 = "7.5.3"
输出: -1
示例 4:
输入:version1 = "1.01", version2 = "1.001"
输出:0
解释:忽略前导零,“01” 和 “001” 表示相同的数字 “1”。
示例 5:
输入:version1 = "1.0", version2 = "1.0.0"
输出:0
解释:version1 没有第三级修订号,这意味着它的第三级修订号默认为 “0”。
'''
双指针i_s,j_s分别遍历v1,v2,以.为分割寻找数字的终点i_e,j_e
x=int(v1[i_s:i_e])
y=int(v1[j_s:j_e])
'''
def f(v1,v2):
l1,l2=len(v1),len(v2)
s1,s2=0,0
print(v1,v2,l1,l2)
while(s1<l1 and s2<l2):
e1,e2=s1,s2
while(e1<l1 and v1[e1]!='.'):
e1+=1
while(e2<l2 and v2[e2]!='.'):
e2+=1
print(s1,e1,s2,e2)
x1=int(v1[s1:e1]) if s1!=e1 else 0
x2=int(v2[s2:e2]) if s2!=e2 else 0
s1, s2 = e1+1, e2+1
print('x:',x1,x2)
if x1>x2:
return 1
if x1<x2:
return -1
return 0
929. 独特的电子邮件地址
难度:简单
题目描述
每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。
例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名。
除了小写字母,这些电子邮件还可能包含 '.' 或 '+'。
如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)
如果在本地名称中添加加号('+'),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 m.y+name@email.com 将转发到 my@email.com。 (同样,此规则不适用于域名。)
可以同时使用这两个规则。
给定电子邮件列表 emails,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?
示例:
输入:["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
输出:2
解释:实际收到邮件的是 "testemail@leetcode.com" 和 "testemail@lee.tcode.com"。
'''
1、找到邮件位置,找到须符合规则的字符段
2、遇到'+'不计后面的;遇到'.'跳过
'''
def uniqueEmail(emails):
res=set()
for email in emails:
t=''
i=0
indexAt=email.index('@')
print(indexAt)
while(i<indexAt and email[i]!='+'):
if(email[i]=='.' ):
i+=1
continue
t+=email[i]
i+=1
t+=email[indexAt:]
res.add(t)
print(res)
return len(res)