各种笔记,太菜了唉/(ㄒoㄒ)/~~
求最长不重复子串(不是子序列)
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
start=0
end=0
L=[]
last_len=0
myset=set()
while startand endif s[end] not in myset:
myset.add(s[end])
end += 1
else:
last_len=len(myset) if last_lenelse last_len
myset.remove(s[start])
start+=1
# 很关键!!!
last_len = len(myset) if last_len < len(myset) else last_len
return last_len
考虑第一次用数组超时了,第二次用的set。基本就是两个指针,start和end,如果end指向一个已经存在的元素,表示set里满足不重复子串,更新长度记录后就start指针后移同时依次弹出set中的元素直到把end指向的元素弹出来。
最后需要考虑一下遍历完成set内还有元素的情况。
别人的解法:
class Solution:
# @return an integer
def lengthOfLongestSubstring(self, s):
start = maxLength = 0
usedChar = {}
for i in range(len(s)):
if s[i] in usedChar and start <= usedChar[s[i]]:
start = usedChar[s[i]] + 1
else:
maxLength = max(maxLength, i - start + 1)
usedChar[s[i]] = i
return maxLength
用了字典,start和i分别指向子串的开头和结尾。字典建立字符到索引的映射,这样可以做到不用一个一个递增start而是调到重复的字符后面,速度快了近一倍。
这种方式次次更新最大长度,而我只是考虑到发现重复才更新。
这个题一般想法就是,直接合并后选择。线性时间复杂度。
如果要logm+logn
呢?
def find_kth_largest(A,B,k):
if len(A)==0:
return B[k-1]
if len(B)==0:
return A[k-1]
#递归边界不必多说
i=len(A)//2
j=len(B)//2
#求各自中间元素下标
if B[j]#为了统一保持B[j]>=A[i]
t=i+j+1
if k<=t:
return find_kth_largest(A[:i],B,k)
else:
return find_kth_largest(A,B[j+1:],k-j-1)
先上源码如是。
主要思路就是每次截断其中一个数组,利用二分查找的思路。
假设有以下数组:
a0 a1 a2 a3 a4 a5… | ai…an-1 an
b0 b1 b2 b3 b4 b5…bj | …bn-1 bn
这里统一让bj>ai
t=i+j+1
表示|
左面元素的个数。
如果k<=t,则k在左面,就可以把右上给删除掉
如果k>t,则k在右面,就可以把左下删除掉
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
# -*- coding:utf-8 -*-
# -*- by prime -*-
class RandomListNode:
def __init__(self, x):
self.label = x
self.next = None
self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
if pHead==None:
return None
self.CloneNodes(pHead)
self.Clonerandoms(pHead)
return self.ListSplit(pHead)
def CloneNodes(self,pHead):
pNode=pHead
while pNode:
pCloneNode=RandomListNode(pNode.label)
pCloneNode.next=pNode.next
pCloneNode.random=None
pNode.next=pCloneNode
pNode=pCloneNode.next
def Clonerandoms(self,pHead):
pNode=pHead
while pNode:
pCloneNode=pNode.next
if pNode.random:
pCloneNode.random=pNode.random.next
pNode=pNode.next.next
def ListSplit(self,pHead):
pNode=pHead
pCloneHead=pHead.next
pCloneNode=pCloneHead
#pNode的指向比pCloneNode快一个
pNode.next=pCloneNode.next
pNode=pNode.next
while pNode:
#总是先变next的指向再递推
pCloneNode.next=pNode.next
pCloneNode=pCloneNode.next
pNode.next=pCloneNode.next
pNode=pNode.next
return pCloneHead
牛客网代码如上,严格按照三部走策略:如下图
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
实际上就是BST的中序遍历序列组成双向链表。学习它人的一个代码如下:
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def Convert(self, pRootOfTree):
# write code here
if pRootOfTree==None:
return None
p=pRootOfTree #指向当前节点
pre=None #指向前一个节点
stack=[]
isfirst=True #第一次遍历需要特别处理根节点
while p!=None or len(stack)!=0:
while p!=None:
stack.append(p)
p=p.left
p=stack.pop()
if isfirst:
pre=p
pRootOfTree=p #根节点是中序遍历第一个节点
isfirst=False
else:
#对p和pre两个节点进行指针操作
pre.right=p
p.left=pre
pre=p
p=p.right
return pRootOfTree
主要就是两个指针和一个栈。。。
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def __init__(self):
self.isbalance=True
def IsBalanced_Solution(self, pRoot):
# write code here
self.getDepth(pRoot)
return self.isbalance
def getDepth(self,pRoot):
if pRoot==None:
return 0
left=self.getDepth(pRoot.left)
right=self.getDepth(pRoot.right)
if abs(left-right)>1:
self.isbalance=False
return right+1 if right>left else left+1