326. Power of Three
Given an integer, write a function to determine if it is a power of three.(判斷一個數是否是3的次方數,不使用循環和迭代)
由于輸入是int,正數范圍是0-231,在此范圍中允許的最大的3的次方數為319=1162261467,那么我們只要看這個數能否被n整除即可。
class Solution(object):
def isPowerOfThree(self, n):
"""
:type n: int
:rtype: bool
"""
return n > 0 and 1162261467 % n ==0
152. Maximum Product Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest product.For example, given the array [2,3,-2,4],the contiguous subarray [2,3] has the largest product = 6
從數組(至少包含一個數字)中找出一個連續的子數組,該子數組的乘積最大。
對于Product Subarray,要考慮到一種特殊情況,即負數和負數相乘:如果前面得到一個較小的負數,和后面一個較大的負數相乘,得到的反而是一個較大的數,如{2,-3,-7},所以,我們在處理乘法的時候,除了需要維護一個局部最大值,同時還要維護一個局部最小值,由此,可以寫出如下的轉移方程式:
big, small=max(n, n*big, n*small), min(n, n*big, n*small)
class Solution(object):
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
maximum=big=small=nums[0]
for n in nums[1:]:
big, small=max(n, n*big, n*small), min(n, n*big, n*small)
maximum=max(maximum, big)
return maximum
155. Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
getMin() -- Retrieve the minimum element in the stack.
利用元組tuple,同時儲存數和最小值。
class MinStack(object):
def __init__(self):
"""
initialize your data structure here.
"""
self.q = []
def push(self, x):
"""
:type x: int
:rtype: void
"""
curMin = self.getMin()
if curMin == None or x < curMin:
curMin = x
self.q.append((x, curMin));
def pop(self):
"""
:rtype: void
"""
self.q.pop()
def top(self):
"""
:rtype: int
"""
if len(self.q) == 0:
return None
else:
return self.q[-1][0]
def getMin(self):
"""
:rtype: int
"""
if len(self.q) == 0:
return None
else:
return self.q[-1][1]
198. House Robber
題目描述:你是一名專業強盜,計劃沿著一條街打家劫舍。每間房屋都儲存有一定數量的金錢,唯一能阻止你打劫的約束條件就是:由于房屋之間有安全系統相連,如果同一個晚上有兩間相鄰的房屋被闖入,它們就會自動聯絡警察,因此不可以打劫相鄰的房屋。給定一列非負整數,代表每間房屋的金錢數,計算出在不驚動警察的前提下一晚上最多可以打劫到的金錢數。
解題思路:
這道題的本質相當于在一列數組中取出一個或多個不相鄰數,使其和最大。 這是一道動態規劃問題。 我們維護一個一位數組dp,其中dp[i]表示到i位置時不相鄰數能形成的最大和。 對于第i個房間我們的選擇是偷和不偷, 如果決定是偷 則第i-1個房間必須不偷 那么 這一步的就是dp[i] = nums(i-1) + dpNotTake[i -1]
, 假設dp[i]表示打劫到第i間房屋時累計取得的金錢最大值.如果是不偷, 那么上一步就無所謂是不是已經偷過, dp[i] = dp[i -1 ], 因此dp[i] =max(dpNotTake[i-1 ] + nums(i-1), dp[i-1] )
其中dpNotTake[i-1]=dp[i-2]
利用動態規劃,狀態轉移方程:dp[i] = max(dp[i - 1], dp[i - 2] + num[i - 1])
其中,dp[i]表示打劫到第i間房屋時累計取得的金錢最大值。
狀態轉移方程:
dp[0] = num[0] (當i=0時)
dp[1] = max(num[0], num[1]) (當i=1時)
dp[i] = max(num[i] + dp[i - 2], dp[i - 1]) (當i !=0 and i != 1時)
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
last, now = 0, 0
for i in nums: last, now = now, max(last + i, now)
return now
***
### 310. Minimum Height Trees
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
>(1)樹是一個無向圖,其中任何2個頂點通過唯一一條路徑連接。
(2) 任何含有n個節點和n-1條邊的連通圖是一棵樹。
(3) 圖中一點的度等于該點的邊的數量。
(4) 葉子節點的度為1,內部節點的度大于等于2。
(5) 一個路徑圖是一棵含有2個及以上的不分支的節點的樹。
(6) 如果一棵樹的一個節點被指定為根,則這棵樹為根樹。
(7) 有根樹的高度是根與葉之間最長的向下路徑上的邊數。
It is very easy to get the idea of two pointers. One from each end and move at the same speed. When they meet or they are one step away, (depends on the parity of n), we have the roots we want.For a tree we can do some thing similar. We start from every end, by end we mean vertex of degree 1 (aka leaves). We let the pointers move the same speed. When two pointers meet, we keep only one of them, until the last two pointers meet or one step away we then find the roots.
It is easy to see that the last two pointers are from the two ends of the longest path in the graph.
The actual implementation is similar to the BFS topological sort. Remove the leaves, update the degrees of inner vertexes. Then remove the new leaves. Doing so level by level until there are 2 or 1 nodes left. What's left is our answer!
>實際類似于BFS(廣度優先算法)。除去葉子(度為1),更新內部頂點的度。然后刪除新的葉子節點。一直繼續下去,直到剩下個1個或2個節點,這就是我們的答案!
The time complexity and space complexity are both O(n).
Note that for a tree we always have V = n, E = n-1.
class Solution(object):
def findMinHeightTrees(self, n, edges):
"""
:type n: int
:type edges: List[List[int]]
:rtype: List[int]
"""
if n == 1: return [0]
adj = [set() for _ in xrange(n)]
for i, j in edges:
adj[i].add(j)
adj[j].add(i)
leaves = [i for i in xrange(n) if len(adj[i]) == 1]
while n > 2:
n -= len(leaves)
newLeaves = []
for i in leaves:
j = adj[i].pop()
adj[j].remove(i)
if len(adj[j]) == 1: newLeaves.append(j)
leaves = newLeaves
return leaves
***
### 318. Maximum Product of Word Lengths
Given a string array`words`, find the maximum value of length`(word[i]) * length(word[j])`where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.
>思路:利用bitmap的方法,將字符串轉換為數字。對于字符串中的每個字符ch,轉換為1<<(ch-‘a‘).只要兩個字符串轉換之后的數字進行&操作結果為0,說明這兩個字符串沒有相同的字符。就可以求這兩個字符串的長度的乘積,和最終要返回的值ret比較,保證ret一直是最大的。為了簡化步驟,可以首先將字符串按照長度進行排序,長度較長的字符串排在前面。這樣,在內部循環之中,只要滿足條件可以計算乘積,內部循環就馬上終止,因為后續就算計算出了乘積也一定比當前計算的乘積值要小。同樣的,在外部循環之中,如果ret>=(words[i].length()*words[i].length()),那么直接終止循環,因為后面計算出的乘積一定比ret要小。
代碼一:
class Solution(object):
def maxProduct(self, words):
"""
:type words: List[str]
:rtype: int
"""
if not words:
return 0
curr_max = 0
while words:
curr_word = set(words[0])
curr_len = len(words[0])
words = words[1:]
for word in words:
for char in curr_word:
if char in word:
break
else:
curr_max = max(curr_max, curr_len*len(word))
return curr_max
代碼二:
class Solution(object):
def maxProduct(self, words):
"""
:type words: List[str]
:rtype: int
"""
maskLen = {reduce(lambda x, y: x | y, [1 << (ord(c) - 97) for c in word], 0): len(word)
for word in sorted(words, key = lambda x: len(x))}.items()
return max([x[1] * y[1] for i, x in enumerate(maskLen) for y in maskLen[:i] if not (x[0] & y[0])] or [0])
>注:
- ord():函數返回值為字符在ASCII碼中的序號
- reduce( ):reduce內建函數是一個二元操作函數,他用來將一個數據集合(鏈表,元組等)中的所有數據進行下列操作:用傳給reduce中的函數 func()(必須是一個二元操作函數)先對集合中的第1,2個數據進行操作,得到的結果再與第三個數據用func()函數運算,最后得到一個結果。第三個參數為0,則先對0和集合中的第一個數據進行操作。
- enumerate( ):遍歷數組。
***
### 90. Subsets II
Given a collection of integers that might contain duplicates, ***nums***, return all possible subsets.
**Note:** The solution set must not contain duplicate subsets.
For example,
If ***nums*** = `[1,2,2] `
a solution is:`[ [2], [1], [1,2,2], [2,2], [1,2], []]`
解(一):
class Solution(object):
def subsetsWithDup(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res=[[]]
for num in nums:
res+=[i +[num] for i in res if i +[num] not in res]
return res
進一步分析選取該元素的條件:
>- 該元素為整個集合中的第一個元素。
- 即該元素下標為 0
- 該元素不等于前一個元素
- 該元素等于前一個元素,但是前一個元素也在我們現在枚舉的子集中
由此可推出解(二):
class Solution:
# @param num, a list of integer
# @return a list of lists of integer
def subsetsWithDup(self, S):
res = [[]]
S.sort()
for i in range(len(S)):
if i == 0 or S[i] != S[i - 1]:
l = len(res)
for j in range(len(res) - l, len(res)):
res.append(res[j] + [S[i]])
return res
>代碼分析:
1. 數列中本身包含空集[ ]
2. 第一輪i=0,l=0,j從0到0,添加[1]
3. 第二輪i=1,s[1]!=s[0],l=1,j從0到1,添加[2],[1,2]
4. 第三輪i=2,s[2]=s[1],l=1,j從3到4,添加[2,2],[1,2,2]
***
### 306. Additive Number
Additive number is a string whose digits can form additive sequence.
A valid additive sequence should contain **at least** three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.
**For example:**`"112358"`is an additive number because the digits can form an additive sequence: `1, 1, 2, 3, 5, 8`
`"199100199"`is also an additive number, the additive sequence is: `1, 99, 100, 199`
**Note:** Numbers in the additive sequence **cannot** have leading zeros, so sequence `1, 2, 03`or `1, 02, 3`is invalid.
Given a string containing only digits` '0'-'9'`, write a function to determine if it's an additive number.
class Solution(object):
def isAdditiveNumber(self, num):
n = len(num)
for i, j in itertools.combinations(range(1, n), 2):
a, b = num[:i], num[i:j]
if b != str(int(b)) or a != str(int(a)):
continue
while j < n:
c = str(int(a) + int(b))
if not num.startswith(c, j):
break
j += len(c)
a, b = b, c
if j == n:
return True
return False
>1. a != str(int(a))用于保證序列不以零開頭
2. print list(itertools.combinations([1,2,3,4],2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
3. num.startswith(c, j) num數列中第一個與c匹配的數字位于j
***
### 322. Coin Change
You are given coins of different denominations and a total amount of money *amount*. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return `-1`
**Example 1:**`coins = [1, 2, 5], amount = 11`
return `3` (11 = 5 + 5 + 1)
**Example 2:**`coins = [2] , amount = 3`
return `-1`
**Note**:You may assume that you have an infinite number of each kind of coin.
>**背景:**
有時會遇到這樣一類題目,它的問題可以分解,但是又不能得出明確的動態規劃或是遞歸解法,此時可以考慮用回溯法解決此類問題。回溯法的優點 在于其程序結構明確,可讀性強,易于理解,而且通過對問題的分析可以大大提高運行效
率。但是,對于可以得出明顯的遞推公式迭代求解的問題,還是不要用回溯 法,因為它花費的時間比較長。
>**回溯法中,首先需要明確下面三個概念**
:(一)約束函數:約束函數是根據題意定出的。通過描述合法解的一般特征用于去除不合法的解,從而避免繼續搜索出這個不合法解的剩余部分。因此,約束函數是對于任何狀態空間樹上的節點都有效、等價的。(二)狀態空間樹:剛剛已經提到,狀態空間樹是一個對所有解的圖形描述。樹上的每個子節點的解都只有一個部分與父節點不同。(三)擴展節點、活結點、死結點:所謂擴展節點,就是當前正在求出它的子節點的節點,在DFS中,只允許有一個擴展節點。活結點就是通過與約束函數的對照,節點本身和其父節點均滿足約束函數要求的節點;死結點反之。由此很容易知道死結點是不必求出其子節點的(沒有意義)。
>**為什么用DFS**
深度優先搜索(DFS)和廣度優先搜索(FIFO)在 分支界限法中,一般用的是FIFO或最小耗費搜索;其思想是一次性將一個節點的所有子節點求出并將其放入一個待求子節點的隊列。通過遍歷這個隊列(隊列在 遍歷過程中不斷增長)完成搜索。而DFS的作法則是將每一條合法路徑求出后再轉而向上求第二條合法路徑。而在回溯法中,一般都用DFS。為什么呢?這是因 為可以通過約束函數殺死一些節點從而節省時間,由于DFS是將路徑逐一求出的,通過在求路徑的過程中殺死節點即可省去求所有子節點所花費的時間。
FIFO 理論上也是可以做到這樣的,但是通過對比不難發現,DFS在以這種方法解決問題時思路要清晰非常多。
>**回溯法可以被認為是一個有過剪枝的DFS過程**
利用回溯法解題的具體步驟首先,要通過讀題完成下面三個步驟:
(1)描述解的形式,定義一個解空間,它包含問題的所有解。
(2)構造狀態空間樹。
(3)構造約束函數(用于殺死節點)。
然后就要通過DFS思想完成回溯,完整過程如下:
(1)設置初始化的方案(給變量賦初值,讀入已知數據等)。
(2)變換方式去試探,若全部試完則轉(7)。
(3)判斷此法是否成功(通過約束函數),不成功則轉(2)。
(4)試探成功則前進一步再試探。
(5)正確方案還未找到則轉(2)。
(6)已找到一種方案則記錄并打印。
(7)退回一步(回溯),若未退到頭則轉(2)。
(8)已退到頭則結束或打印無解。
class Solution(object):
def coinChange(self, coins, amount):
coins.sort(reverse = True)
lenc, self.res = len(coins), 2**31-1
def dfs(pt, rem, count):
if not rem:
self.res = min(self.res, count)
for i in range(pt, lenc):
if coins[i] <= rem < coins[i] * (self.res-count): # if hope still exists
dfs(i, rem-coins[i], count+1)
for i in range(lenc):
dfs(i, amount, 0)
return self.res if self.res < 2**31-1 else -1
***
### 88. Merge Sorted Array
Given two sorted integer arrays *nums1* and *nums2*, merge *nums2* into *nums1* as one sorted array.
**Note:**You may assume that *nums1* has enough space (size that is greater or equal to *m* + *n*) to hold additional elements from *nums2*. The number of elements initialized in *nums1*and *nums2* are *m* and *n* respectively.
比較如下兩種方法:
(1)
class Solution(object):
def merge(self, nums1, m, nums2, n):
while n > 0:
if m <= 0 or nums2[n-1] >= nums1[m-1]:
nums1[m+n-1] = nums2[n-1]
n -= 1
else:
nums1[m+n-1] = nums1[m-1]
m -= 1
(2)
class Solution(object):
def merge(self, nums1, m, nums2, n):
while m > 0 and n > 0:
if nums1[m-1] >= nums2[n-1]:
nums1[m+n-1] = nums1[m-1]
m -= 1
else:
nums1[m+n-1] = nums2[n-1]
n -= 1
if n > 0:
nums1[:n] = nums2[:n]
>(1)更加簡潔,思考為什么? 因為(1)中的循環能夠保證`num2`中的數全部添加到`num1`,而(2)不行。
***
### 98. Validate Binary Search Tree
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys **less than** the node's key.
- The right subtree of a node contains only nodes with keys **greater - than** the node's key.
- Both the left and right subtrees must also be binary search trees.
Definition for a binary tree node.
class TreeNode(object):
def init(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def isValidBST(self, root, floor=float('-inf'), ceiling=float('inf')):
if not root:
return True
if root.val <= floor or root.val >= ceiling:
return False
# in the left branch, root is the new ceiling;
return self.isValidBST(root.left, floor, root.val) and
self.isValidBST(root.right, root.val, ceiling)
>Python中可以用如下方式表示正負無窮:float("inf"), float("-inf")
***
### 96. Unique Binary Search Trees
Given *n*, how many structurally unique **BST's** (binary search trees) that store values 1...*n*?
>假如整個樹有 *n* 個節點,根節點為 *1* 個節點,兩個子樹平分剩下的 *n-1* 個節點。
假設我們已經知道節點數量為 *x* 的二叉樹有`dp[x]`種不同的形態。
則一顆二叉樹左節點節點數量為 *k* 時,其形態數為`dp[k] * dp[n - 1 - k]`。
而對于一顆 *n* 個節點的二叉樹,其兩個子樹分配節點的方案有 *n-1* 種:
```(0, n-1), (1, n-2), ..., (n-1, 0)```
因此我們可以得到對于 ***i* **個節點的二叉樹,其形態有:
for j in xrange(i):
res[i] += res[j] * res[i-1-j]
并且可以發現,dp數組有遞推關系,我們可以使用遞推或是記憶化搜索來實現。
邊界條件為dp[0] = 1。
dp(dynamic-programming)動態規劃解:
class Solution(object):
def numTrees(self, n):
res = [0] * (n+1)
res[0] = 1
for i in xrange(1, n+1):
for j in xrange(i):
res[i] += res[j] * res[i-1-j]
return res[n]
利用**卡塔蘭數**:
Catalan Number (2n)!/((n+1)!*n!)
def numTrees(self, n):
return math.factorial(2n)/(math.factorial(n)math.factorial(n+1))
>**卡塔蘭數**是[組合數學](http://baike.baidu.com/view/44868.htm)中一個常在各種計數問題中出現的數列。
卡塔蘭數列的前幾項為 [注: n = 0, 1, 2, 3, … n]:
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …
***
### 46. Permutations
Given a collection of **distinct** numbers, return all possible permutations.
For example,
`[1,2,3]`have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
class Solution(object):
def permute(self, nums):
return map(list, itertools.permutations(nums))
***
### 80. Remove Duplicates from Sorted Array II
Follow up for "Remove Duplicates":What if duplicates are allowed at most *twice*?
For example,Given sorted array *nums* = `[1,1,1,2,2,3]`,
Your function should return length = `5`,
with the first five elements of *nums* being `1, 1, 2, 2, 3`.
It doesn't matter what you leave beyond the new length.
class Solution(object):
def removeDuplicates(self, nums):
i = 0
for n in nums:
if i < 2 or n > nums[i-2]:
nums[i] = n
i += 1
return i
>注:不能去掉`i<2`,因為考慮`nums`中只有一個元素的情況下`n = nums[-2]`,`return i = 0 ` 不符合實際。
***
### 19. Remove Nth Node From End of List
Given a linked list, remove the *n* th
node from the end of list and return its head.
Definition for singly-linked list.
class ListNode(object):
def init(self, x):
self.val = x
self.next = None
class Solution:
def removeNthFromEnd(self, head, n):
fast = slow = head
for _ in range(n):
fast = fast.next
if not fast:
return head.next
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return head
***
### 179. Largest Number
Given a list of non negative integers, arrange them such that they form the largest number.
For example, given `[3, 30, 34, 5, 9]`, the largest formed number is `9534330`.
Note: The result may be very large, so you need to return a string instead of an integer.
>1. we define a function that compares two string (`a , b`) . we consider a bigger than b if `a+b>b+a` for example : (`a = 2, b = 11`) a is bigger than b because `211` >`112`
>2. convert all elements of the list from int to string
>3. sort the list descendingly using the comparing function we defined for example sorting this list `["2","11","13"]` using the function defined in step 1 would produce` ["2","13","11"]`
>4. we concatatenate the list `21311`
class Solution:
@param num, a list of integers
@return a string
def largestNumber(self, num):
comp=lambda a,b:1 if a+b>b+a else -1 if a+b<b+a else 0
num=map(str,num)
num.sort(cmp=comp,reverse=True)
return str(int("".join(num)))
***
### 300. Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,Given `[10, 9, 2, 5, 3, 7, 101, 18]`,
The longest increasing subsequence is `[2, 3, 7, 101]`,
therefore the length is`4`.
Note that there may be more than one LIS combination, it is only necessary for you to return the length.
>**tails**
is an array storing the smallest tail of all increasing subsequences with length `i+1` in `tails[i]`. For example, say we have nums = `[4,5,6,3]`, then all the available increasing subsequences are:
len = 1 : [4], [5], [6], [3] => tails[0] = 3
len = 2 : [4, 5], [5, 6] => tails[1] = 5
len = 3 : [4, 5, 6] => tails[2] = 6
We can easily prove that tails is a increasing array. Therefore it is possible to do a binary search in tails array to find the one needs update.
>Each time we only do one of the two:
(1) if x is larger than all tails, append it, increase the size by 1
(2) if tails[i-1] < x <= tails[i], update tails[i]
Doing so will maintain the tails invariant. The the final answer is just the size.
class Solution(object):
def lengthOfLIS(self, nums):
tails = [0] * len(nums)
size = 0
for x in nums:
i, j = 0, size
while i != j:
m = (i + j) / 2
if tails[m] < x:
i = m + 1
else:
j = m
tails[i] = x
size = max(i + 1, size)
return size
***
### 142. Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return `null`.
Consider the following linked list,
where E is the cylce entry and X,
the crossing point of fast and slow.
H: distance from head to cycle entry E
D: distance from E to X
L: cycle length
If fast and slow both start at head, when fast catches slow,
slow has traveled H+D and fast 2(H+D).
Assume fast has traveled n loops in the cycle,
we have: 2H + 2D = H + D + L --> H + D = nL --> H = nL - D
Thus if two pointers start from head and X,
respectively, one first reaches E, the other also reaches E.
In my solution, since fast starts at head.next,
we need to move slow one step forward in the beginning of part 2
Definition for singly-linked list.
class ListNode(object):
def init(self, x):
self.val = x
self.next = None
class Solution:
# @param head, a ListNode
# @return a list node
def detectCycle(self, head):
try:
fast = head.next
slow = head
while fast is not slow:
fast = fast.next.next
slow = slow.next
except:
# if there is an exception, we reach the end and there is no cycle
return None
# since fast starts at head.next, we need to move slow one step forward
slow = slow.next
while head is not slow:
head = head.next
slow = slow.next
return head
>1.[參考答案](https://leetcode.com/discuss/43146/share-my-python-solution-with-detailed-explanation)
***
### 16. 3Sum Closest
Given an array *S* of *n* integers, find three integers in *S* such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
>比較簡單,不解釋了
class Solution:
# @return an integer
def threeSumClosest(self, num, target):
num.sort()
result = num[0] + num[1] + num[2]
for i in range(len(num) - 2):
j, k = i+1, len(num) - 1
while j < k:
sum = num[i] + num[j] + num[k]
if sum == target:
return sum
if abs(sum - target) < abs(result - target):
result = sum
if sum < target:
j += 1
elif sum > target:
k -= 1
return result
***
### 141. Linked List Cycle
Given a linked list, determine if it has a cycle in it.
>解釋見142
Definition for singly-linked list.
class ListNode(object):
def init(self, x):
self.val = x
self.next = None
class Solution(object):
def hasCycle(self, head):
try:
slow = head
fast = head.next
while slow is not fast:
slow = slow.next
fast = fast.next.next
return True
except:
return False
***
### 143. Reorder List
Given a singly linked list *L*: *L*0→*L*1→…→*L**n*-1→*L*n,
reorder it to: *L*0→*L**n*→*L*1→*L**n*-1→*L*2→*L**n*-2→…
You must do this in-place without altering the nodes' values.
For example,Given `{1,2,3,4}`, reorder it to` {1,4,2,3}`.
>
Definition for singly-linked list.
class ListNode(object):
def init(self, x):
self.val = x
self.next = None
class Solution(object):
def reorderList(self, head):
if not head:
return
# find the mid point
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# reverse the second half in-place
pre, node = None, slow
while node:
pre, node.next, node = node, pre, node.next
# Merge in-place; Note : the last node of "first" and "second" are the same
first, second = head, pre
while second.next:
first.next, first = second, first.next
second.next, second = first, second.next
return
> 對于`pre, node.next, node = node, pre, node.next`,此處并非通常意義上的賦值,可以看作更接近與指針順序的調換。(如果僅僅是多變量賦值,則不需要第三個變量來暫時儲存,可看成元組) [參考](https://leetcode.com/discuss/11122/a-python-solution-o-n-time-o-1-space)
***
### 221. Maximal Square
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 4.
class Solution(object):
def maximalSquare(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
rows, max_size = len(matrix), 0
'''
size[i]: the current number of continuous '1's in a column of matrix.
Reset when discontinued.
The idea is to do a by-row scan, updating size[i]
Then check if there are continuous elements in size whose value is
bigger than current maximal size.
'''
if rows > 0:
cols = len(matrix[0])
size = [0] * cols
for x in xrange(rows):
# update size
count, size = 0, map(lambda x, y: x+1 if y == '1' else 0, size, matrix[x])
for y in xrange(cols):
# check if it exceeds current maximal size
if size[y] > max_size:
count += 1
if count > max_size:
# increase maximal size by 1
max_size += 1
break
else:
count = 0
return max_size*max_size
>理解map()函數的用法
***
### 134. Gas Station
There are *N* gas stations along a circular route, where the amount of gas at station *i* is gas[i].
You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station *i* to its next station (*i*+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
**Note:**The solution is guaranteed to be unique.
class Solution(object):
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
if len(gas) == 0 or len(cost) == 0 or sum(gas) < sum(cost):
return -1
position = 0
balance = 0 # current tank balance
for i in range(len(gas)):
balance += gas[i] - cost[i] # update balance
if balance < 0: # balance drops to negative, reset the start position
balance = 0
position = i+1
return position
>If the total number of gas is bigger than the total number of cost. There must be a solution.
***
### 347. Top K Frequent Elements
Given a non-empty array of integers, return the ***k*** most frequent elements.
For example,
Given `[1,1,1,2,2,3]` and k = 2, return `[1,2]`.
**Note: **
You may assume *k* is always valid, 1 ≤ *k* ≤ number of unique elements.
Your algorithm's time complexity **must be** better than O(*n* log *n*), where *n* is the array's size.
import collections
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
# Use Counter to extract the top k frequent elements
# most_common(k) return a list of tuples, where the first item of the tuple is the element,
# and the second item of the tuple is the count
return [i[0] for i in collections.Counter(nums).most_common(k)]
***
### 48. Rotate Image
You are given an *n* x *n* 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Follow up:Could you do this in-place?
**Most Pythonic - [::-1] and zip**
The most pythonic solution is a simple one-liner using [::-1] to flip the matrix upside down and thenzip to transpose it. It assigns the result back into A, so it's "in-place" in a sense and the OJ accepts it as such, though some people might not.
class Solution:
def rotate(self, A):
A[:] = zip(*A[::-1])
>[zip()函數](http://www.cnblogs.com/frydsh/archive/2012/07/10/2585370.html)
**Flip Flip**
Basically the same as the first solution, but using reverse instead of [::-1] and transposing the matrix with loops instead of zip. It's 100% in-place, just instead of only moving elements around, it also moves the rows around.
class Solution:
def rotate(self, A):
A.reverse()
for i in range(len(A)):
for j in range(i):
A[i][j], A[j][i] = A[j][i], A[i][j]
###