I finally finished all the 154 Leetcode problems in Python.
In my blog, I try to post the most succinct and effective Python solutions to Leetcode problems. You are more than welcome to post your solutions in the comments if you think yours are better.
I will add on explanations to the solutions later.
I also want to thank the following two bloggers. 水中的鱼 explains the algorithms in a clear and succinct way. Kitt's blog is the best Python leetcode solution blog so far.
Friday, September 19, 2014
Leetcode: Max Points on a Line @Python
# Definition for a point
# class Point:
# def __init__(self, a=0, b=0):
# self.x = a
# self.y = b
class Solution:
# @param points, a list of Points
# @return an integer
def maxPoints(self, points):
if len(points)==0: return 0
n=len(points)
maxnum=1
for i in range(n):
dic={'inf':0}
same=0
for j in range(n):
if points[i].x==points[j].x and points[i].y==points[j].y:
same+=1
else:
slope='inf' if points[i].x==points[j].x else 1.0*(points[i].y-points[j].y)/(points[i].x-points[j].x)
if slope not in dic:
dic[slope]=1
else:
dic[slope]+=1
maxnum=max(maxnum,max(dic.values())+same)
return maxnum
Leetcode: Valid Number @Python
Finite State Machine Solution:
class Solution:
# @param s, a string
# @return a boolean
def isNumber(self, s):
s=s.rstrip(' ')
s=s.lstrip(' ')
trans=[[1,2,3,-1], #state 0:start
[1,-1,7,4], #state 1:digit
[1,-1,3,-1], #state 2: +/-
[7,-1,-1,-1], #state 3:.dot
[5,6,-1,-1], #state 4:e/E
[5,-1,-1,-1], #state 5: exponent
[5,-1,-1,-1], #state 6: exponent+/-
[7,-1,-1,4]] #state 7: .digits
state=0
for char in s:
if char in '0123456789':
inputs=1
elif char in '+-':
inputs=2
elif char=='.':
inputs=3
elif char in 'eE':
inputs=4
else:
return False
state=trans[state][inputs-1]
if state==-1:return False
if state==1 or state==5 or state==7:
return True
else:
return False
You can use the following code to find all corner cases.
Cheat Code:
class Solution:
# @param s, a string
# @return a boolean
def isNumber(self, s):
try:
float(s) # If error is shown then print False else True
return True
except:
return False
Leetcode: Word Ladder II @Python
class Solution:
# @param start, a string
# @param end, a string
# @param dict, a set of string
# @return a list of lists of string
def findLadders(self, start, end, dict):
alph = [chr(c) for c in range(97, 123)]
def buildpath(path, word):
if len(prevMap[word])==0:
path.append(word); currPath=path[:]
currPath.reverse(); result.append(currPath)
path.pop();
return
path.append(word)
for iter in prevMap[word]:
buildpath(path, iter)
path.pop()
result=[]
prevMap={}
dict.add(end)
dict.add(start)
length=len(start)
for i in dict:
prevMap[i]=[]
candidates=[set(),set()]; current=0; previous=1
candidates[current].add(start)
while end not in candidates[current]:
current, previous=previous, current
for i in candidates[previous]: dict.remove(i)
candidates[current].clear()
for word in candidates[previous]:
for i in range(length):
part1=word[:i]; part2=word[i+1:]
for j in alph:
if word[i]!=j:
nextword=part1+j+part2
if nextword in dict:
prevMap[nextword].append(word)
candidates[current].add(nextword)
if len(candidates[current])==0: return result
buildpath([], end)
return result
Leetcode: Wildcard Matching @Python
class Solution:
# @param s, an input string
# @param p, a pattern string
# @return a boolean
def isMatch(self, s, p):
n=len(s)
m=len(p)
i=0
j=0
star=0
s_coor=None
while i<n:
if j<m and (s[i]==p[j] or p[j]=='?'):
j+=1
i+=1
elif j<m and p[j]=='*':
s_coor=i
star=j
j+=1
elif s_coor!=None:
i=s_coor+1
j=star+1
s_coor+=1
else:
return False
while j<m and p[j]=='*':
j+=1
if j==m:
return True
else:
return False
Leetcode: Text Justification @Python
class Solution:
# @param words, a list of strings
# @param L, an integer
# @return a list of strings
def fullJustify(self, words, L):
def gen(queue,num,blanks):
line=[]
if num==1:
item=queue.pop()
line=item+''.join([' ']*(L-len(item)))
rst.append(line)
return
spare=blanks%(num-1)
while queue:
word=queue.popleft()
space=blanks//(num-1)+1 if spare>0 else blanks//(num-1)
spare-=1
if queue:
line.append(word+''.join([' ']*space))
else:
line.append(word)
rst.append(''.join(line))
queue=collections.deque([])
rst=[]
n=0
num=0
while words:
if n+len(words[0])<=L:
queue.append(words[0])
n+=len(words[0])+1
num+=1
words.pop(0)
else:
blanks=L-n+num if n<=L else num-1
gen(queue,num,blanks)
num=0
n=0
line=' '.join(list(queue))
rst.append(line+''.join([' ']*(L-len(line))))
return rst
Leetcode: LRU Cache @Python
class LRUCache:
# @param capacity, an integer
def __init__(self, capacity):
LRUCache.dic=collections.OrderedDict()
LRUCache.capacity=capacity
LRUCache.size=0
# @return an integer
def get(self, key):
try:
value=LRUCache.dic[key]
del LRUCache.dic[key]
LRUCache.dic[key]=value
return value
except KeyError:
return -1
# @param key, an integer
# @param value, an integer
# @return nothing
def set(self, key, value):
try:
del LRUCache.dic[key]
LRUCache.dic[key]=value
except:
if LRUCache.size==LRUCache.capacity:
LRUCache.dic.popitem(False)
LRUCache.dic[key]=value
else:
LRUCache.size+=1
LRUCache.dic[key]=value
Leetcode: Reverse Words in a String @Python
class Solution:
# @param s, a string
# @return a string
def reverseWords(self, s):
return " ".join(s.split()[::-1])
Leetcode: Surrounded Regions @Python
class Solution:
# @param board, a 9x9 2D array
# Capture all regions by modifying the input board in-place.
# Do not return any value.
def solve(self, board):
def fill(x, y):
if x<0 or x>m-1 or y<0 or y>n-1 or board[x][y] != 'O': return
queue.append((x,y))
board[x][y]='D'
def bfs(x, y):
if board[x][y]=='O':queue.append((x,y)); fill(x,y)
while queue:
curr=queue.pop(0); i=curr[0]; j=curr[1]
fill(i+1,j);fill(i-1,j);fill(i,j+1);fill(i,j-1)
if len(board)==0: return
m=len(board); n=len(board[0]); queue=[]
for i in range(n):
bfs(0,i); bfs(m-1,i)
for j in range(1, m-1):
bfs(j,0); bfs(j,n-1)
for i in range(m):
for j in range(n):
if board[i][j] == 'D': board[i][j] = 'O'
elif board[i][j] == 'O': board[i][j] = 'X'
Leetcode: String to Integer (atoi) @Python
Cheating with int():
class Solution:
# @return an integer
def atoi(self, str):
str = str.strip()
newStr = []
for i in range(len(str)):
if '0' <= str[i] <= '9' or (str[i] in ('+', '-') and i == 0):
newStr.append(str[i])
else:
break
if newStr in ([], ['+'], ['-']):
return 0
elif -2147483648 <= int(''.join(newStr)) <= 2147483647:
return int(''.join(newStr))
elif int(''.join(newStr)) > 2147483647:
return 2147483647
else:
return -2147483648
Without cheating:
class Solution:
# @return an integer
def atoi(self, Str):
dic={"0":0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
rst=0
validset='+-0123456789'
numberset='0123456789'
INT_MAX="2147483647"
INT_MIN="2147483648"
Str=Str.lstrip(' ')
for i in range(len(Str)):
if Str[i] not in validset:
Str=Str[:i]
break
if (len(Str)==1 and Str in '+-') or ('-' in Str[1:] or '+' in Str[1:]) or len(Str)==0:
return 0
sign=1
if Str[0]=='-':
sign=-1
Str=Str[1:]
elif Str[0]=='+':
Str=Str[1:]
if len(Str)>10:
return -2147483648 if sign==-1 else 2147483647
elif len(Str)==10:
overflow=True
if sign==-1:
for i in range(10):
if Str[i]<INT_MIN[i]:
overflow=False
break
if overflow:
return -2147483648
else:
for i in range(10):
if Str[i]<INT_MAX[i]:
overflow=False
break
if overflow:
return 2147483647
for i in range(len(Str)):
if sign==1:
rst+=dic[Str[i]]*(10**(len(Str)-i-1))
else:
rst-=dic[Str[i]]*(10**(len(Str)-i-1))
return rst
else:
for i in range(len(Str)):
rst+=dic[Str[i]]*(10**(len(Str)-i-1))
return rst*sign
Leetcode: Decode Ways @Python
class Solution:
# @param s, a string
# @return an integer
def numDecodings(self, s):
n=len(s)
dp=[0]*(n)
if n==0: return 0
if s[0]!='0':
dp[0]=1
else:
return 0
for i in range(1,n):
if s[i]=='0':
if s[i-1] in '12':
if i<2:
dp[i]=1
else:
dp[i]=dp[i-2]
else:
return 0
elif s[i-1]=='0':
dp[i]=dp[i-1]
else:
if int(s[i-1:i+1])<=26:
if i<2:
dp[i]=2
else:
dp[i]=dp[i-1]+dp[i-2]
else:
dp[i]=dp[i-1]
return dp[n-1]
Leetcode: Divide Two Integers @Python
class Solution:
# @return an integer
def divide(self, dividend, divisor):
sign = 1 if (dividend > 0 and divisor > 0) or (dividend < 0 and divisor < 0) else -1
dividend = abs(dividend)
divisor = abs(divisor)
quotient = 0
while dividend >= divisor:
k = 0; tmp = divisor
while dividend >= tmp:
quotient += 1 << k
dividend -= tmp
tmp <<= 1
k += 1
return quotient if sign==1 else -quotient
Leetcode: Word Break II @Python
class Solution:
# @param s, a string
# @param dict, a set of string
# @return a list of strings
def wordBreak(self, s, dict):
n=len(s)
A=[[] for i in range(n)]
i=n-1
while i>=0:
if s[i:n] in dict:
A[i].append(n)
for j in range(i+1,n):
if A[j] and s[i:j] in dict:
A[i]+=[j]
i-=1
path=[[0]]
rst=[]
while path:
new_path=[]
for i in path:
if i[-1]==n:
temp=[s[i[k]:i[k+1]] for k in range(len(i)-1)]
rst.append(' '.join(temp))
else:
for node in A[i[-1]]:
new_path.append(i+[node])
path=new_path
return rst
Leetcode: 3Sum @Python
class Solution:
# @return a list of lists of length 3, [[val1,val2,val3]]
def threeSum(self, num):
A=sorted(num)
n=len(A)
rst=[]
for k in range(n-2):
a=A[k]
if k>0 and a==A[k-1]:
continue
i=k+1
j=n-1
while j>i:
s2=A[i]+A[j]
if s2==-A[k]:
rst.append([A[k],A[i],A[j]])
while j>i:
i+=1
j-=1
if A[i]!=A[i-1] or A[j]!=A[j+1]:
break
elif A[k]+s2>0:
while j>i:
j-=1
if A[j]!=A[j+1]:
break
else:
while j>i:
i+=1
if A[i]!=A[i-1]:
break
return rst
Leetcode: Median of Two Sorted Arrays @Python
class Solution:
# @return a float
def getMedian(self, A, B, k):
# return kth smallest number of arrays A and B, assume len(A) <= len(B)
lenA = len(A); lenB = len(B)
if lenA > lenB: return self.getMedian(B, A, k)
if lenA == 0: return B[k-1]
if k == 1: return min(A[0], B[0])
pa = min(k/2, lenA); pb = k - pa
return self.getMedian(A[pa:], B, k - pa) if A[pa - 1] <= B[pb - 1] else self.getMedian(A, B[pb:], k - pb)
def findMedianSortedArrays(self, A, B):
lenA = len(A); lenB = len(B)
if (lenA + lenB) % 2 == 1:
return self.getMedian(A, B, (lenA + lenB) / 2 + 1)
else:
return 0.5 * ( self.getMedian(A, B, (lenA + lenB) / 2) + self.getMedian(A, B, (lenA + lenB) / 2 + 1) )
Leetcode: Substring with Concatenation of All Words @Python
class Solution:
# @param S, a string
# @param L, a list of string
# @return a list of integer
def findSubstring(self, S, L):
n,m,w=len(S),len(L),len(L[0])
rst=[]
for index in xrange(n-m*w+1):
seg=[S[i:i+w] for i in xrange(index,index+m*w,w)]
for item in L:
if item in seg:
seg.remove(item)
else:
break
if seg==[]:rst.append(index)
return rst
Leetcode: Minimum Window Substring @Python
class Solution:
# @return a string
def minWindow(self, S, T):
count1={};
for char in T:
if char not in count1: count1[char]=1
else: count1[char]+=1
count=len(T)
start=0; minSize=len(S)+1; minStart=0
for end in range(len(S)):
if S[end] in count1:
count1[S[end]]-=1
if count1[S[end]]>=0:
count-=1
if count==0:
while True:
if S[start] in count1:
if count1[S[start]]<0:
count1[S[start]]+=1
else:
break
start+=1
if minSize>end-start+1:
minSize=end-start+1; minStart=start
if minSize==len(S)+1: return ''
else:
return S[minStart:minStart+minSize]
Leetcode: Palindrome Partitioning II @Python
Use Manacher's algorithm with O(n)
O(n^2) Dynamic Programming is not optimal.
My Manacher's algorithm implementation got TLE.
I learn from the solution here.
class Solution:
# @param s, s string
# @return an array
def _buildPalindromeCache(self, s):
transformed = "#" + "#".join(s) + "#"
palindrome_len = [1] * len(transformed)
center = 0
farest = 0
for index in xrange(1, len(transformed)):
if farest <= index:
tryingLen = 1
else:
preComputedLen = palindrome_len[2*center-index]
if preComputedLen + index > farest:
tryingLen = farest + 1 - index
else:
palindrome_len[index] = preComputedLen
continue
while index + tryingLen < len(transformed) and \
index - tryingLen >= 0:
if transformed[index + tryingLen] == \
transformed[index - tryingLen]:
tryingLen += 1
else:
break
if index + tryingLen -1 > farest:
farest = index + tryingLen -1
center = index
palindrome_len[index] = tryingLen
return palindrome_len
# @param begin, an integer
# @param end, an integer
# @param palindromeCache, an array
# @return a boolean
#def _isPalindrome(self, begin, end, palindromeCache):
''' In palindromeCache, the index for s[index] and s[end] are
index*2+1 and end*2+1 respectively. So in palindromeCache, the
middle point of s[index] and s[end] is (index*2+1 + end*2+1) // 2,
that is (index + end + 1).
IF you remove this function and use a single statement instead, you
could get a 30%-40% performance improvement or even more.
'''
# return palindromeCache[begin + end + 1] - 1 >= (end - begin + 1)
# @param s, a string
# @return an integer
def minCut(self, s):
''' Solve it in a dynamic programming method.
'''
if len(s) == 0: return 0
palindromeCache = self._buildPalindromeCache(s)
minCutEndingHere = [0] * len(s)
for index in xrange(1, len(s)):
if palindromeCache[index + 1] - 1 >= (index + 1):
# The substring from beginning to here is a palindrome. No
# cut is needed.
minCut = 0
else:
# We could add a cut between index and index - 1.
minCut = 1 + minCutEndingHere[index-1]
# Or the cut could be tried between tryingToCut and
# tryingToCut - 1.
for tryingToCut in xrange(1, index):
# Only when s[tryingToCut : index+1] is palindrome, the
# cut could be done.
if palindromeCache[tryingToCut + index + 1] - 1 >= (index - tryingToCut + 1):
minCut = min(minCut, \
1 + minCutEndingHere[tryingToCut-1])
minCutEndingHere[index] = minCut
return minCutEndingHere[-1]
Leetcode: Word Ladder @Python
class Solution:
# @param start, a string
# @param end, a string
# @param dict, a set of string
# @return an integer
def ladderLength(self, start, end, dic):
alph = [chr(c) for c in range(97, 123)]
dic.add(end)
n,m=len(dic),len(start)
que=collections.deque([[start,1]])
while que:
crt=que.popleft()
crtword,crtlen=crt[0],crt[1]
if crtword==end: return crtlen
for i in range(m):
s1=crtword[:i]
s2=crtword[i+1:]
for c in alph:
nextword=s1+c+s2
if nextword in dic and c!=crtword[i]:
dic.remove(nextword)
que.append([nextword,crtlen+1])
return 0
Leetcode: Two Sum @Python
class Solution:
# @return a tuple, (index1, index2)
def twoSum(self, num, target):
dict={}
for i in range(len(num)):
res=target-num[i]
if res in dict:
return (dict[res],i+1)
else:
dict[num[i]]=i+1
return (-1,-1)
Leetcode: Candy @Python
class Solution:
# @param ratings, a list of integer
# @return an integer
def candy(self, ratings):
n=len(ratings)
candynum=[1]*n
for i in range(1,n):
if ratings[i]>ratings[i-1]:
candynum[i]=candynum[i-1]+1
for i in reversed(range(n-1)):
if ratings[i]>ratings[i+1] and candynum[i]<=candynum[i+1]:
candynum[i]=candynum[i+1]+1
return sum(candynum)
Leetcode: Interleaving String @Python
class Solution:
# @return a boolean
def isInterleave(self, s1, s2, s3):
n=len(s1)
m=len(s2)
l=len(s3)
if l!=n+m:return False
match=[[True]*(m+1) for i in range(n+1)]
for i in range(1,n+1):
match[i][0]=match[i-1][0] and s1[i-1]==s3[i-1]
for j in range(1,m+1):
match[0][j]=match[0][j-1] and s2[j-1]==s3[j-1]
for i in range(1,n+1):
for j in range(1,m+1):
match[i][j]=(s3[i+j-1]==s1[i-1] and match[i-1][j]) or (s3[i+j-1]==s2[j-1] and match[i][j-1])
return match[n][m]
Leetcode: Longest Valid Parentheses @Python
class Solution:
# @param s, a string
# @return an integer
def longestValidParentheses(self, s):
n=len(s)
stack=[(')',-1)]
maxlen=0
for i in range(n):
if s[i]==')' and stack[-1][0]=='(':
stack.pop()
maxlen=max(maxlen,i-stack[-1][1])
else:
stack.append((s[i],i))
return maxlen
Leetcode: Simplify Path @Python
class Solution:
# @param path, a string
# @return a string
def simplifyPath(self, path):
stack=[]
pathlist=path.split('/')
for i in pathlist:
if i==''or i=='.':
continue
elif i=='..':
if len(stack)>=1:
stack.pop()
else:
stack.append(i)
rst='/'+'/'.join(stack)
if rst=='':
return '/'
return rst
Thursday, September 18, 2014
Leetcode: Word Search @Python
class Solution:
# @param board, a list of lists of 1 length string
# @param word, a string
# @return a boolean
def exist(self, board, word):
self.totalRow, self.totalCol = len(board), len(board[0])
for i in xrange(self.totalRow):
for j in xrange(self.totalCol):
if board[i][j] == word[0]:
if self.dfs(board, i, j, word[1:]): return True
return False
def dfs(self, board, r, c, word):
if len(word) == 0: return True
increm=[[1,0],[-1,0],[0,1],[0,-1]]
for [i,j] in increm:
if self.totalRow>r+i>=0 and self.totalCol>c+j>=0 and board[r+i][c+j] == word[0]:
ch, board[r][c] = board[r][c], '#'
if self.dfs(board, r+i, c+j, word[1:]): return True
board[r][c] = ch
return False
Leetcode: Evaluate Reverse Polish Notation @Python
class Solution:
# @param tokens, a list of string
# @return an integer
def evalRPN(self, tokens):
stack = []
for i in tokens:
if i not in ('+', '-', '*', '/'):
stack.append(int(i))
else:
op2 = stack.pop()
op1 = stack.pop()
if i == '+': stack.append(op1 + op2)
elif i == '-': stack.append(op1 - op2)
elif i == '*': stack.append(op1 * op2)
else: stack.append(int(op1 * 1.0 / op2))
return stack[0]
Leetcode: Regular Expression Matching @Python
class Solution:
# @return a boolean
def isMatch(self, s, p):
dp=[[False for i in range(len(p)+1)] for j in range(len(s)+1)]
dp[0][0]=True
for i in range(1,len(p)+1):
if p[i-1]=='*':
if i>=2:
dp[0][i]=dp[0][i-2]
for i in range(1,len(s)+1):
for j in range(1,len(p)+1):
if p[j-1]=='.':
dp[i][j]=dp[i-1][j-1]
elif p[j-1]=='*':
dp[i][j]=dp[i][j-1] or dp[i][j-2] or (dp[i-1][j] and (s[i-1]==p[j-2] or p[j-2]=='.'))
else:
dp[i][j]=dp[i-1][j-1] and s[i-1]==p[j-1]
return dp[len(s)][len(p)]
Leetcode: Binary Tree Maximum Path Sum @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param root, a tree node
# @return an integer
pathsum=-2**31
def sumpath(self,root):
subsum=-2**31
if not root:
return 0
else:
lsum=self.sumpath(root.left)
rsum=self.sumpath(root.right)
subsum=max(lsum+root.val,rsum+root.val,root.val)
self.pathsum=max(subsum,lsum+rsum+root.val,self.pathsum)
return subsum
def maxPathSum(self, root):
if not root: return None
self.sumpath(root)
return self.pathsum
Leetcode: Reorder List @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @return nothing
def reorderList(self, head):
if not head or not head.next: return head
#find the middle node
slow=fast=ListNode(0)
slow.next=head
n=0#length of the rear half of the linked list
while fast and fast.next:
n+=1
slow=slow.next
fast=fast.next.next
if not fast:
n=n-1
mid=slow
rear=mid.next
mid.next=None
dummy=ListNode(0)
for i in range(n):
temp=dummy.next
dummy.next=rear
rear=rear.next
dummy.next.next=temp
crt=head
insert_node=dummy.next
for i in reversed(range(n)):
temp=crt.next
crt.next=insert_node
insert_node=insert_node.next
crt.next.next=temp
crt=temp
return head
Leetcode: Restore IP Addresses @Python
class Solution:
# @param s, a string
# @return a list of strings
def restoreIpAddresses(self, s):
n=len(s)
rst=[(0,[])]
for i in range(4):
newlist=[]
for elem in rst:
if (4-i)*3>=n-elem[0]:
for k in range(1,4):
if elem[0]+k<=n and (s[elem[0]]!='0' or k==1) and 0<=int(s[elem[0]:elem[0]+k])<=255:
newlist.append((k+elem[0],elem[1]+[s[elem[0]:elem[0]+k]]))
rst=newlist
res=[]
for elem in rst:
if elem[0]==n:
res.append('.'.join(elem[1]))
return res
Leetcode: Multiply Strings @Python
class Solution:
# @param num1, a string
# @param num2, a string
# @return a string
def multiply(self, num1, num2):
n=len(num1)
m=len(num2)
num1=[int(i) for i in reversed(num1)]
num2=[int(i) for i in reversed(num2)]
if n*m==0:
return None
elif num1==[0] or num2==[0]:
return '0'
rst=[0]*(m+n)
for i in range(n):
for j in range(m):
a2,a1=divmod(num1[i]*num2[j],10) #c1,c2<=1
c1,rst[i+j]=divmod(a1+rst[i+j],10)
c2,rst[i+j+1]=divmod(a2+c1+rst[i+j+1],10)
k=2
while c2:
c2,rst[i+j+k]=divmod(c2+rst[i+j+k],10)
k+=1
if rst[n+m-1]:
return ''.join(map(str,reversed(rst)))
else:
return ''.join(map(str,reversed(rst[:n+m-1])))
Leetcode: Sort List @Python
class Solution:
def sortList(self, head):
# QuickSort
len = 0
tail = head
while tail != None:
len += 1
tail = tail.next
pivot = head
return self.partition(head, len)
def partition(self, head, len):
if len<2:
return head
pivot = head
r_pivot = pivot
tail = head
head = ListNode(0)
left = head
l = 0
lr = 0
stall = 0
l_len = 0
r_len = len-1
while tail.next != None and l<len-1:
if tail.next.val < pivot.val:
left.next = tail.next
left = left.next
tail.next = tail.next.next
r_len -= 1
l_len += 1
lr += 1
left.next = pivot
elif tail.next.val > pivot.val:
tail = tail.next
elif tail.next.val == pivot.val:
self.swap_nodes(r_pivot, r_pivot.next, tail, tail.next)
lr += 1
stall = l-lr
if r_pivot == tail:
tail = r_pivot.next
r_pivot = r_pivot.next
r_len -= 1
if stall>0:
stall -= 1
else:
l += 1
left.next = pivot
head_l = self.partition(head.next, l_len)
head_r = self.partition(r_pivot.next, r_len)
head.next = head_l
r_pivot.next = head_r
return head.next
def swap_nodes(self, x, a, y, b):
x.next = b
y.next = a
temp = a.next
a.next = b.next
b.next = temp
Leetcode: Insert Interval @Python
class Solution:
# @param intervals, a list of Intervals
# @param newInterval, a Interval
# @return a list of Interval
def insert(self, intervals, newInterval):
ans, inserted = [], False
for i in range(len(intervals)):
if intervals[i].end < newInterval.start:
ans.append(intervals[i])
elif intervals[i].start > newInterval.end:
if not inserted:
inserted = True
ans.append(newInterval)
ans.append(intervals[i])
else:
newInterval.start = min(newInterval.start, intervals[i].start)
newInterval.end = max(newInterval.end, intervals[i].end)
if len(ans) == 0 or newInterval.start > ans[-1].end:
ans.append(newInterval)
return ans
Leetcode: Spiral Matrix @Python
class Solution:
# @param matrix, a list of lists of integers
# @return a list of integers
def spiralOrder(self, matrix):
rst=[]
m=len(matrix)
if m>0:
n=len(matrix[0])
else:
return rst
up=0
down=m-1
left=0
right=n-1
while up<=down and left<=right:
rst.extend(matrix[up][left:right+1])
up+=1
if up<=down:
for i in range(up,down+1): rst.append(matrix[i][right])
right-=1
else:
break
if left<=right:
for i in reversed(range(left,right+1)): rst.append(matrix[down][i])
down-=1
else:
break
if down>=up:
for i in reversed(range(up,down+1)): rst.append(matrix[i][left])
left+=1
else:
break
return rst
Leetcode: Longest Palindromic Substring @Python
class Solution:
# @return a string
def longestPalindrome(self, s):
n=len(s)
inputstr=s
s=list(s)
i=0
L=2*n+1
#insert '#' into the string so that the even and odd palidrome are the same
while i<L:
s.insert(i,'#')
i+=2
right=0
P=[0]*L
mid=0
for i in range(1,L):
if i<right:
mirror=2*mid-i
if i+P[mirror]<right:
P[i]=P[mirror]
continue
else:
P[i]=right-i
j=P[i]+1
while 0<=i-j and i+j<L and s[i-j]==s[i+j]:
P[i]+=1
j+=1
mid=i
right=mid+P[i]
index,maxlen=max(enumerate(P),key=operator.itemgetter(1))
seq=int(index//2-P[index]// 2)
rst=inputstr[seq:seq+P[index]]
return rst
Leetcode: Merge Intervals @Python
# Definition for an interval.
# class Interval:
# def __init__(self, s=0, e=0):
# self.start = s
# self.end = e
class Solution:
# @param intervals, a list of Interval
# @return a list of Interval
def merge(self, intervals):
intervals=sorted(intervals,key=lambda x:x.start)
n=len(intervals)
if not n: return []
rst=[intervals[0]]
i=0
for i in range(1,n):
if rst[-1].end<intervals[i].start:
rst.append(intervals[i])
else:
temp=Interval(rst[-1].start,max(rst[-1].end,intervals[i].end))
rst.pop()
rst.append(temp)
return rst
Leetcode: Sudoku Solver @Python
class Solution:
# @param board, a 9x9 2D array
# Solve the Sudoku by modifying the input board in-place.
# Do not return any value.
def solveSudoku(self, board):
lt, rt, bt = [0] * 9, [0] * 9, [0] * 9
self.dt = {}
for i in range(9): self.dt[1<<i] = chr(ord('1')+i)
for i in range(9):
board[i] = list(board[i])
for j in range(9):
if (board[i][j] == '.'):
continue;
num = ord(board[i][j]) - ord('1')
lt[i] |= 1 << num
rt[j] |= 1 << num
bt[j//3*3+i//3] |= 1 << num
self.dfs(board, 0, lt, rt, bt)
board = [''.join(s) for s in board]
def dfs(self, board, p, lt, rt, bt):
while p < 81 and board[p//9][p%9] != '.':
p += 1
if p == 81:
return True
i, j, k = p//9, p%9, p%9//3*3+p//9//3
can = (~(lt[i]|rt[j]|bt[k])) & ((1<<9)-1)
while can:
num = can&-can
board[i][j] = self.dt[num]
lt[i] |= num
rt[j] |= num
bt[k] |= num
if self.dfs(board, p + 1, lt, rt , bt):
return True
board[i][j] = '.'
lt[i] &= ~num
rt[j] &= ~num
bt[k] &= ~num
can -= num
return False
Leetcode: Word Break @Python
class Solution:
# @param s, a string
# @param dict, a set of string
# @return a boolean
def wordBreak(self, s, dict):
n=len(s)
dp=[False for i in range(n)]
for i in range(1,n+1):
if s[:i] in dict:
dp[i-1]=True
for j in range(1,i):
if dp[j-1] and s[j:i] in dict:
dp[i-1]=True
return dp[n-1] if n>0 else '' in dict
Leetcode: Largest Rectangle in Histogram @Python
class Solution:
# @param height, a list of integer
# @return an integer
def largestRectangleArea(self, height):
height.insert(0,0)
height.append(0)
n=len(height)
stack=[0]
maxRec=0
for i in range(1,n):
while height[i]<height[stack[-1]]:
k=stack.pop()
newarea=(i-1-stack[-1])*height[k]
if newarea>maxRec:
maxRec=newarea
stack.append(i)
return maxRec
Leetcode: Maximal Rectangle @Python
class Solution:
# @param matrix, a list of lists of 1 length string
# @return an integer
def largestRectangleArea(self, height):
height.insert(0,0)
height.append(0)
n=len(height)
stack=[0]
maxRec=0
for i in range(1,n):
while height[i]<height[stack[-1]]:
k=stack.pop()
newarea=(i-1-stack[-1])*height[k]
if newarea>maxRec:
maxRec=newarea
stack.append(i)
height.pop()
height.pop(0)
return maxRec
def maximalRectangle(self, matrix):
maxRec=0
m=len(matrix)
if m>0:
n=len(matrix[0])
else:
return 0
height=[[0 for i in range(n)] for j in range(m)]
for i in range(m):
for j in range(n):
if i==0:
height[i][j]=int(matrix[i][j])
elif matrix[i][j]=='0':
height[i][j]=0
else :
height[i][j]=height[i-1][j]+1
maxRec=max(maxRec,self.largestRectangleArea(height[i]))
return maxRec
Leetcode: 4Sum @Python
class Solution:
# @return a list of lists of length 4, [[val1,val2,val3,val4]]
def fourSum(self, num, target):
n=len(num)
D={}
A=sorted(num)
rst=[]
for i in range(n-1):
for j in range(i+1,n):
psum=A[i]+A[j]
if psum in D:
if [i,j] not in D[psum]:
D[psum]+=[[i,j]]
else:
D[psum]=[[i,j]]
if target-psum in D:
for elem in D[target-psum]:
if (i not in elem) and (j not in elem):
temp=sorted([A[i],A[j],A[elem[0]],A[elem[1]]])
if temp not in rst:
rst.append(temp)
return rst
Leetcode: Implement strStr() @Python
class Solution:
# @param haystack, a string
# @param needle, a string
# @return a string or None
# @KMP algorithms
def ComputePrefixFunction(self, needle):
Pi = [0 for i in range(len(needle))]
m = len(needle)
Pi[0] = 0
k = 0
for q in range(1, m):
while k > 0 and needle[k] != needle[q]:
k = Pi[k - 1]
if needle[k] == needle[q]:
k = k + 1
Pi[q] = k
return Pi
def strStr(self, haystack, needle):
n = len(haystack)
m = len(needle)
if m == 0:
return haystack
Pi = self.ComputePrefixFunction(needle)
q = 0
for i in range(0, n):
while q > 0 and needle[q] != haystack[i]:
q = Pi[q - 1]
if needle[q] == haystack[i]:
q = q + 1
if q == m:
return haystack[i - m + 1:]
return None
Leetcode: Merge k Sorted Lists @Python
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param a list of ListNode
# @return a ListNode
def mergeKLists(self, lists):
heap = [(node.val, node) for node in lists if node]
heapq.heapify(heap)
curr=head = ListNode(0)
while heap:
curr.next= heapq.heappop(heap)[1]
curr = curr.next
if curr.next: heapq.heappush(heap, (curr.next.val, curr.next))
return head.next
Leetcode: Permutation Sequence @Python
class Solution:
# @return a string
def getPermutation(self, n, k):
rst=''
crt=k-1
num=[str(i+1) for i in range(n)]
for i in reversed(range(n)):
digit=num[crt//math.factorial(i)]
if crt!=0:
rst=rst+digit
num.remove(digit)
else:
rst=rst+''.join(num)
break
crt=crt%math.factorial(i)
return rst
Leetcode: Rotate List @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @param k, an integer
# @return a ListNode
def rotateRight(self, head, k):
if not head: return None
test=head
n=1
while test.next:
test=test.next
n+=1
test.next=head
for i in range(n-k%n):
test=test.next
rst=test.next
test.next=None
return rst
Leetcode: Best Time to Buy and Sell Stock III @Python
Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete at most two transactions. Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Recall that the problem Best Time Buy and Sell Stock solved the problem with one transaction. This problem is just the sum of the previous problem for day 1 to day i and that for day i to the end. Recording the maximum of all the sum profits for each i-th day will render the result. For each sub-problem of the i-th day, the time complex is O(n), and the problem III is O(n^2). We can optimize by construct two arrays of the maximum one-transaction profit for day 1 to day i and that for day i to the end. Thus, we do not need to re-calculate two parts of the summation every single time. The optimized time complexity is O(n).
class Solution:
# @param prices, a list of integer
# @return an integer
def maxProfit(self, prices):
n=len(prices)
if not prices: return 0
mpf=[0 for i in range(n)] #max profit for the first transaction. forward
mpb=[0 for i in range(n)] #max profit for the last transaction. backwrd
low_price=prices[0]
high_price=prices[-1]
for i in range(1,n):
low_price=min(low_price,prices[i])
mpf[i]=max(mpf[i-1],prices[i]-low_price)
for i in reversed(range(n-1)):
high_price=max(high_price,prices[i])
mpb[i]=max(mpb[i+1],high_price-prices[i])
Mprofit=0
for i in range(n-1):
Mprofit=max(Mprofit,mpf[i]+mpb[i])
return Mprofit
Leetcode: Longest Substring Without Repeating Characters @Python
class Solution:
# @return an integer
def lengthOfLongestSubstring(self, s):
start=0
n=len(s)
substr=''
maxlen=0
for end in range(n):
if s[end] not in substr:
substr+=s[end]
else:
substr=''
maxlen=max(maxlen,end-start)
for i in xrange(start,end):
if s[end]==s[i]:
start=i+1
substr=s[start:end+1]
break
maxlen=max(maxlen,n-start)
return maxlen
Leetcode: Sqrt(x) @Python
class Solution:
# @param x, an integer
# @return an integer
def sqrt(self, x):
a=1000.0#guess
new_a=(a*1.0+x/a)/2
while int(new_a)!=int(a):
a=new_a
new_a=(a*1.0+x/a)/2
return int(a)
Leetcode: First Missing Positive @Python
class Solution:
# @param A, a list of integers
# @return an integer
def firstMissingPositive(self, A):
n=len(A)
if n==0: return 1
for i in xrange(n):
while A[i]>0 and A[i]<=n and A[i]!=i+1 and A[i]!=A[A[i]-1]:
temp=A[i]
A[i]=A[A[i]-1]
A[temp-1]=temp
for i in xrange(n):
if A[i]!=i+1:
missing=i+1
return missing
return n+1
Leetcode: Scramble String @Python
class Solution:
# @return a boolean
def isScramble(self, s1, s2):
if len(s1)!=len(s2): return False
if s1==s2: return True
l1=list(s1); l2=list(s2)
l1.sort();l2.sort()
if l1!=l2: return False
length=len(s1)
for i in range(1,length):
if self.isScramble(s1[:i],s2[:i]) and self.isScramble(s1[i:],s2[i:]): return True
if self.isScramble(s1[:i],s2[length-i:]) and self.isScramble(s1[i:],s2[:length-i]): return True
return False
Leetcode: Clone Graph @Python
# Definition for a undirected graph node
# class UndirectedGraphNode:
# def __init__(self, x):
# self.label = x
# self.neighbors = []
class Solution:
# @param node, a undirected graph node
# @return a undirected graph node
# dps
def cloneGraph(self, node):
if not node: return None
def dfs(input, dic):
if input in dic: return dic[input]
newnode=UndirectedGraphNode(input.label)
dic[input]=newnode
for neighbor in input.neighbors:
newnode.neighbors.append(dfs(neighbor,dic))
return newnode
return dfs(node,{})
Leetcode: Valid Palindrome @Python
class Solution:
# @param s, a string
# @return a boolean
def isPalindrome(self, s):
pattern = re.compile('[\W_]+')
A=pattern.sub('', s.lower())
if A==A[::-1]:
return True
else:
return False
Leetcode: Add Two Numbers @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @return a ListNode
def addTwoNumbers(self, l1, l2):
num1,num2=0,0
digit=0
while l1:
num1+=l1.val*(10**digit)
l1=l1.next
digit+=1
digit=0
while l2:
num2+=l2.val*(10**digit)
l2=l2.next
digit+=1
numsum=num1+num2
numsum,val=divmod(numsum,10)
keephead=head=ListNode(val)
while numsum:
numsum,val=divmod(numsum,10)
crt=ListNode(val)
head.next=crt
head=crt
return keephead
Friday, September 12, 2014
Leetcode: Copy List with Random Pointer @Python
# Definition for singly-linked list with a random pointer.
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
if not head: return None
keephead=head
while head:
crt=RandomListNode(head.label)
crt.next=head.next
head.next=crt
head=crt.next
head=keephead
while head:
crt=head.next
if head.random:
crt.random=head.random.next
head=crt.next
newhead=keephead.next
head=keephead
while head:
crt=head.next
head.next=crt.next
if crt.next:
crt.next=crt.next.next
head=head.next
return newhead
Leetcode: Recover Binary Search Tree @Python
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param root, a tree node
# @return a tree node
def recoverTree(self, root):
if not root: return None
pre=parent=f1=f2=None# dummy node
foundfirst=False
crt=root
while crt:
if crt.left:
pre=crt.left
while pre.right and pre.right!=crt:
pre=pre.right
if not pre.right:
pre.right=crt
crt=crt.left
else:
pre.right=None
if parent.val>crt.val:
if not foundfirst:
f1=parent
foundfirst=True
f2=crt
parent=crt
crt=crt.right
else:
if parent and parent.val>crt.val:
if not foundfirst:
f1=parent
foundfirst=True
f2=crt
parent=crt
crt=crt.right
if f1 and f2:
f1.val,f2.val=f2.val,f1.val
return root
Leetcode: Anagrams @Python
class Solution:
# @param strs, a list of strings
# @return a list of strings
def anagrams(self, strs):
dic={}
res=[]
for word in strs:
S_word=''.join(sorted(word))
dic[S_word]=[word] if S_word not in dic else dic[S_word]+[word]
for i in dic:
if len(dic[i])>1:
res+=dic[i]
return res
Leetcode: ZigZag Conversion @Python
class Solution:
# @return a string
def convert(self, s, nRows):
if nRows==1: return s
tmp=['' for i in range(nRows)]
index=-1; step=1
for i in range(len(s)):
index+=step
if index==nRows:
index-=2; step=-1
elif index==-1:
index=1; step=1
tmp[index]+=s[i]
return ''.join(tmp)
Leetcode: Combination Sum II @Python
class Solution:
# @param candidates, a list of integers
# @param target, integer
# @return a list of lists of integers
def combinationSum2(self, candidates, target):
A=sorted(candidates)
n=len(A)
stack=[([A[i]],i,A[i]) for i in range(n) if A[i]<target]
rst=[]
for i in A:
if i==target:
rst=[[i]]
break
while stack:
new_stack=[]
for i in stack:
for j in range(i[1]+1,n):
crt_sum=i[2]+A[j]
if crt_sum<target:
new_stack.append((i[0]+[A[j]],j,crt_sum))
elif crt_sum==target and (i[0]+[A[j]] not in rst):
rst.append(i[0]+[A[j]])
stack=new_stack[:]
return rst
Leetcode: Jump Game II @Python
class Solution:
# @param A, a list of integers
# @return an integer
def jump(self, A):
n=len(A)
reach=0
if n<=1: return 0
jumpNum=0
while True:
jumpNum+=1
for i in range(reach+1):
reach=max(reach, i+A[i])
if reach>=n-1:
return jumpNum
Leetcode: Distinct Subsequences @Python
class Solution:
# @return an integer
def numDistinct(self, S, T):
s=len(S)
t=len(T)
dp=[[0 for j in range(s+1)] for i in range(t+1)]
for j in range(s+1):
dp[0][j]=1
for j in range(1,s+1):
for i in range(1,min(j+1,t+1)):
if T[i-1]!=S[j-1]:
dp[i][j]=dp[i][j-1]
else:
dp[i][j]=dp[i-1][j-1]+dp[i][j-1]
return dp[t][s]
Leetcode: Reverse Nodes in k-Group @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @param k, an integer
# @return a ListNode
def reverse(self, start, end):
newhead=ListNode(0); newhead.next=start
while newhead.next!=end:
tmp=start.next
start.next=tmp.next
tmp.next=newhead.next
newhead.next=tmp
return [end, start]
def reverseKGroup(self, head, k):
if head==None: return None
nhead=ListNode(0); nhead.next=head; start=nhead
while start.next:
end=start
for i in range(k-1):
end=end.next
if end.next==None: return nhead.next
res=self.reverse(start.next, end.next)
start.next=res[0]
start=res[1]
return nhead.next
Leetcode: Remove Duplicates from Sorted List II @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @return a ListNode
def deleteDuplicates(self, head):
nhead=pre=ListNode(0)
pre.next=head
crt=head
flag=0
while crt and crt.next:
if crt.next.val==crt.val:
crt.next=crt.next.next
flag=1
else:
if flag==0:
crt=crt.next
pre=pre.next
else:
pre.next=crt.next
crt=crt.next
flag=0
if flag==1:
pre.next=crt.next
return nhead.next
Leetcode: Permutations II @Python
class Solution:
# @param num, a list of integer
# @return a list of lists of integers
def permuteUnique(self, num):
n=len(num)
if n<=1:
return [num]
rst=[]
num.sort()
cur=0
pre=None
for cur in range(n):
if num[cur]==pre:
continue
pre=num[cur]
for i in self.permuteUnique(num[:cur]+num[cur+1:]):
rst.append(i+[num[cur]])
return rst
Leetcode: Insertion Sort List @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @return a ListNode
def insertionSortList(self, head):
if not head: return None
nextH=ListNode(0)
nextH.next=head
crt=head
while crt.next:
if crt.next.val>=crt.val:
crt=crt.next
continue
cmpr=nextH.next
last=nextH
while crt.next.val>cmpr.val:
last=cmpr
cmpr=cmpr.next
temp=crt.next.next
last.next=crt.next
crt.next.next=cmpr
crt.next=temp
return nextH.next
Leetcode: Edit Distance @Python
class Solution:
# @return an integer
def minDistance(self, word1, word2):
n=len(word1)
m=len(word2)
M=max(n,m)
dp=[[M for i in range(m+1)] for j in range(n+1)]
for i in range(n+1):
dp[i][m]=n-i
for i in range(m+1):
dp[n][i]=m-i
for i in reversed(range(n)):
for j in reversed(range(m)):
if word1[i]==word2[j]:
dp[i][j]=dp[i+1][j+1]
else:
dp[i][j]=1+min(dp[i+1][j],dp[i][j+1],dp[i+1][j+1])
return dp[0][0]
Leetcode: Next Permutation @Python
class Solution:
# @param num, a list of integer
# @return a list of integer
def nextPermutation(self, num):
k=len(num)
if k==1:
return num
left=-1
for i in range(k-2,-1,-1):
if num[i]<num[i+1]:
left=i
break
for i in range(k-1,-1,-1):
if num[i]>num[left]:
right=i
break
if left>=0:
num[left],num[right]=num[right],num[left]
l=left+1
else:
l=0
while l<k-1:
num[l],num[k-1]=num[k-1],num[l]
l+=1
k-=1
return num
Leetcode: Gas Station @Python
class Solution:
# @param gas, a list of integers
# @param cost, a list of integers
# @return an integer
def canCompleteCircuit(self, gas, cost):
n=len(gas)
Sum=total=0
k=0
for i in range(n):
Sum+=gas[i]-cost[i]
total+=gas[i]-cost[i]
if Sum<0:
k=i+1
Sum=0
return k if total>=0 else -1
Leetcode: Validate Binary Search Tree @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param root, a tree node
# @return a boolean
def iterVBST(self,root,m,M):
if root==None: return True
if root.val>=M or root.val<=m: return False
return self.iterVBST(root.left,m,root.val) and self.iterVBST(root.right,root.val,M)
def isValidBST(self, root):
return self.iterVBST(root,-2147483648,2147483647)
Leetcode: Palindrome Partitioning @Python
class Solution:
# @param s, a string
# @return a list of lists of string
def isPalindrome(self, s):
pattern = re.compile('[\W_]+')
A=pattern.sub('', s.lower())
return A==A[::-1]
def partition(self, s):
n=len(s)
rst=[]
stack=[([],0)]
ptable=[[False for i in range(n)] for j in range(n)]
for i in range(n):
for j in range(i+1,n+1):
ptable[i][j-1]=self.isPalindrome(s[i:j])
i=0
while stack:
crt=[]
for i in stack:
if i[1]==n:
rst.append(i[0])
continue
j=i[1]+1
while j<=n:
if ptable[i[1]][j-1]==True:
temp=i[0]+[s[i[1]:j]]
crt.append((temp,j))
j+=1
stack=crt
return rst
Leetcode: Pow(x, n) @Python
class Solution:
# @param x, a float
# @param n, a integer
# @return a float
def pow(self, x, n):
if n==0:
return 1
elif n==1:
return x
elif n%2==0:
return pow(x*x,n/2)
else:
return pow(x*x,n/2)*x
Leetcode: Add Binary @Python
class Solution:
# @param a, a string
# @param b, a string
# @return a string
def addBinary(self, a, b):
n=len(a)
m=len(b)
if n>=m:
c=a[:n-m]
else:
c=b[:m-n]
flag=0
rst=''
i=-1
while -i<=min(n,m):
if a[i]=='1' and b[i]=='1':
if flag==0:
rst='0'+rst
else:
rst='1'+rst
flag=1
elif a[i]=='0' and b[i]=='0':
if flag==0:
rst='0'+rst
else:
rst='1'+rst
flag=0
elif flag==0:
rst='1'+rst
flag=0
else:
rst='0'+rst
flag=1
i-=1
for i in reversed(range(abs(n-m))):
if c[i]=='1' and flag==1:
rst='0'+rst
flag=1
elif c[i]=='0' and flag==1:
rst='1'+rst
flag=0
else:
rst=c[i]+rst
flag=0
if flag==1:
rst='1'+rst
return rst
Leetcode: N-Queens @Python
class Solution:
# @return a list of lists of string
def under_attack(self,col, queens):
return col in queens or any(abs(col - x) == len(queens)-i for i,x in enumerate(queens))
def solve(self,n):
solutions = [[]]
for row in range(n):
solutions = (solution+[i]
for solution in solutions # first for clause is evaluated immediately,
# so "solutions" is correctly captured
for i in range(n)
if not self.under_attack(i, solution))
return solutions
def solveNQueens(self, n):
slt=[]
for j in self.solve(n):
if len(j)==n:
slt.append(list('.'*i+'Q'+'.'*(n-1-i) for i in j))
return slt
Leetcode: Reverse Linked List II @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @param m, an integer
# @param n, an integer
# @return a ListNode
def reverseBetween(self, head, m, n):
if not head: return None
before=ListNode(0)
before.next=head
fast=slow=head
for i in range(m-1):
before=slow
slow=slow.next
for i in range(n-1):
fast=fast.next
for i in range(n-m):
before.next=slow.next
slow.next=fast.next
fast.next=slow
slow=before.next
return before.next if m==1 else head
Leetcode: Letter Combinations of a Phone Number @Python
class Solution:
# @return a list of strings, [s1, s2]
def letterCombinations(self, digits):
dic={'1':'','2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz','0':''}
rst=['']
for i in digits:
rst=[j+k for j in rst for k in dic[i]]
return rst
Leetcode: Construct Binary Tree from Inorder and Postorder Traversal @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param inorder, a list of integers
# @param postorder, a list of integers
# @return a tree node
def buildTree(self, inorder, postorder):
if not inorder: return None
root=TreeNode(postorder[-1])
rootidx=inorder.index(postorder[-1])
root.left=self.buildTree(inorder[:rootidx],postorder[:rootidx])
root.right=self.buildTree(inorder[1+rootidx:],postorder[rootidx:-1])
return root
Leetcode: Construct Binary Tree from Preorder and Inorder Traversal @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param preorder, a list of integers
# @param inorder, a list of integers
# @return a tree node
def buildTree(self, preorder, inorder):
if not inorder: return None
root=TreeNode(preorder[0])
rootidx=inorder.index(preorder[0])
root.left=self.buildTree(preorder[1:1+rootidx],inorder[:rootidx])
root.right=self.buildTree(preorder[1+rootidx:],inorder[1+rootidx:])
return root
Leetcode: Combination Sum @Python
class Solution:
# @param candidates, a list of integers
# @param target, integer
# @return a list of lists of integers
def combinationSum(self, candidates, target):
A=sorted(candidates)
stack=[[i] for i in A if i<target]
rst=[]
for i in A:
if i==target:
rst=[[i]]
break
while stack:
new_stack=[]
for i in stack:
for j in A:
if i[-1]>j:
continue
else:
crt_sum=sum(i+[j])
if crt_sum<target:
new_stack.append(i+[j])
elif crt_sum==target:
rst.append(i+[j])
stack=new_stack[:]
return rst
Leetcode: Binary Tree Zigzag Level Order Traversal @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param root, a tree node
# @return a list of lists of integers
def zigzagLevelOrder(self, root):
crt=[root]
rst=[]
if not crt:
return []
flag=1
while crt!=[None]*len(crt):
if flag==1:
rst.append([i.val for i in crt])
else:
temp=[i.val for i in crt]
temp.reverse()
rst.append(temp)
nextlvl=[]
for i in crt:
if i.left:
nextlvl.append(i.left)
if i.right:
nextlvl.append(i.right)
crt=nextlvl
flag*=-1
return rst
Leetcode: Triangle @Python
class Solution:
# @param triangle, a list of lists of integers
# @return an integer
def minimumTotal(self, triangle):
n=len(triangle)
if n==0:return 0
sv=[triangle[0][0]]
for i in range(1,n):# given sv for row i, calculate sv for row i+1
new_sum=[0 for x in range(i+1)]
for j in range(i+1):
if j==0:
new_sum[0]=triangle[i][0]+sv[0]
elif j==i:
new_sum[i]=triangle[i][i]+sv[i-1]
else:
new_sum[j]=min(triangle[i][j]+sv[j-1],triangle[i][j]+sv[j])
sv=new_sum[:]
return min(sv)
Leetcode: Partition List @Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @param x, an integer
# @return a ListNode
def partition(self, head, x):
if not head: return head
nless=less=ListNode(0)
ngeq=geq=ListNode(0)
pre,crt=None,head
while crt:
pre=crt
crt=crt.next
if pre.val<x:
less.next=pre
less=pre
less.next=None
else:
geq.next=pre
geq=pre
geq.next=None
less.next=ngeq.next
return nless.next
Leetcode: Path Sum II @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param root, a tree node
# @param sum, an integer
# @return a list of lists of integers
def pathSum(self, root, sum):
stack=[]
if root:
stack=[([root],root.val)]
else:
return []
rst=[]
while stack:
crt=[]
for i in stack:
if i[0][-1].left==None and i[0][-1].right==None and i[1]==sum:
rst.append([j.val for j in i[0]])
if i[0][-1].left:
temp=i[0]+[i[0][-1].left]
crt.append((temp,i[1]+i[0][-1].left.val))
if i[0][-1].right:
temp=i[0]+[i[0][-1].right]
crt.append((temp,i[1]+i[0][-1].right.val))
stack=crt[:]
return rst
Leetcode: Subsets II @Python
class Solution:
# @param num, a list of integer
# @return a list of lists of integer
def subsetsWithDup(self, S):
res = [[]]
for e in sorted(S):
res = res+[l+[e] for l in res if l+[e] not in res]
return res
Leetcode: 3Sum Closest @Python
class Solution:
# @return an integer
def threeSumClosest(self, num, target):
A=sorted(num)
n=len(A)
rst=[A[0],A[1],A[2]]
crt=abs(A[0]+A[1]+A[2]-target)
for k in range(n-2):
a=A[k]
if k>0 and a==A[k-1]:
continue
i=k+1
j=n-1
while j>i:
gap=A[i]+A[j]+A[k]-target
if abs(gap)<crt:
rst=[A[k],A[i],A[j]]
crt=abs(gap)
while j>i:
if A[i]+A[j]+A[k]-target>0:
j-=1
if A[j]!=A[j+1]:
break
else:
i+=1
if A[i]!=A[i-1]:
break
return sum(rst)
Leetcode: Jump Game @Python
class Solution:
# @param A, a list of integers
# @return a boolean
def canJump(self, A):
crt=-1
for i in range(len(A)-1):
crt=max(crt-1,A[i])
if crt==0:
return False
return True
Leetcode: Longest Common Prefix @Python
class Solution:
# @return a string
def longestCommonPrefix(self, strs):
if len(strs) == 0:
return ""
for i in range(len(strs[0])):
for j in range(len(strs)):
if len(strs[j]) <= i or strs[j][i] != strs[0][i]:
return (strs[0])[0 : i]
return strs[0]
Leetcode: Convert Sorted List to Binary Search Tree @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a list node
# @return a tree node
def AtoBST(self,A):
n=len(A)
if n==0:
return None
else:
ml=n//2
A[ml].right=self.AtoBST(A[ml+1:])
A[ml].left=self.AtoBST(A[:ml])
return A[ml]
def sortedListToBST(self, head):
A=[]
while head:
A.append(TreeNode(head.val))
head=head.next
return self.AtoBST(A)
Leetcode: Unique Binary Search Trees II @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
#@return a list of tree node with value range from start to end
def TreeGen(self, start,end):
if start>end:
return [None]
rst=[]
for rVal in range(start, end+1):
leftlist=self.TreeGen(start,rVal-1)
rightlist=self.TreeGen(rVal+1,end)
for i in leftlist:
for j in rightlist:
root=TreeNode(rVal)
root.left=i
root.right=j
rst.append(root)
return rst
# @return a list of tree node
def generateTrees(self, n):
return self.TreeGen(1,n)
Leetcode: Count and Say @Python
class Solution:
# @return a string
def itergen(self,a):
k,last,result = 1,a[0],''
for i in range(1,len(a)):
if last==a[i]:k+=1
else:
result = result+str(k)+last
k=1
last = a[i]
result = result+str(k)+last
return result
def countAndSay(self, n):
if n==0: return ''
rst='1'
for i in range(n-1):
rst=self.itergen(rst)
return rst
Leetcode: Search for a Range @Python
class Solution:
# @param A, a list of integers
# @param target, an integer to be searched
# @return a list of length 2, [index1, index2]
def searchRange(self, A, target):
left,right,idx=0,len(A)-1,-1
while left<=right:
mid=(left+right)//2
if A[mid]==target:
idx=mid
break
elif A[mid]<target:
left=mid+1
elif A[mid]>target:
right=mid-1
if idx==-1:
return [-1,-1]
rl,rr=left,right
ml=mr=mid
while rl<ml:
mml=(rl+ml)//2
if A[mml]==target:
ml=mml
else:
rl=mml+1
while rr>mr:
mmr=-((-rr-mr)//2)
if A[mmr]==target:
mr=mmr
else:
rr=mmr-1
return [rl, rr]
Leetcode: Unique Paths II @Python
class Solution:
# @param obstacleGrid, a list of lists of integers
# @return an integer
def uniquePathsWithObstacles(self, obstacleGrid):
row=len(obstacleGrid)
col=len(obstacleGrid[0])
if row*col==0:
return 1
dp=[[0 for i in range(col)] for j in range(row)]
for i in range(row):
if obstacleGrid[i][0]==0:
dp[i][0]=1
else:
break
for j in range(col):
if obstacleGrid[0][j]==0:
dp[0][j]=1
else:
break
for i in range(1,row):
for j in range(1,col):
if obstacleGrid[i][j]==1:
dp[i][j]=0
else:
dp[i][j]=dp[i-1][j]+dp[i][j-1]
return dp[row-1][col-1]
Tuesday, September 9, 2014
Leetcode: Valid Sudoku @Python
class Solution:
# @param board, a 9x9 2D array
# @return a boolean
def isValidSudoku(self, board):
for i in range(9):
dup=[]
for j in range(9):
if board[i][j]!='.':
if board[i][j] in dup:
return False
else:
dup.append(board[i][j])
for j in range(9):
dup=[]
for i in range(9):
if board[i][j]!='.':
if board[i][j] in dup:
return False
else:
dup.append(board[i][j])
for i in [0,3,6]:
for j in [0,3,6]:
dup=[]
for m in range(3):
for n in range(3):
if board[i+n][j+m]!='.':
if board[i+n][j+m] in dup:
return False
else:
dup.append(board[i+n][j+m])
return True
Leetcode: Subsets @Python
class Solution:
# @param S, a list of integer
# @return a list of lists of integer
def subsets(self, S):
res = [[]]
for e in sorted(S):
res = res+[l+[e] for l in res]
return res
Leetcode: Flatten Binary Tree to Linked List @Python
# Definition for a binary tree node
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# @param root, a tree node
# @return nothing, do it in place
def flatten(self, root):
stack=[]
crt=root
while crt:
if crt.right:
stack.append(crt.right)
crt.right=None
if crt.left:
crt.right=crt.left
crt.left=None
crt=crt.right
else:
if stack:
crt.right=stack.pop()
crt=crt.right
else:
break
Subscribe to:
Comments
(
Atom
)