感覺這裏開始的題目開始有難度,不再是想到什麼寫什麼也能通過,要理清思路
696. Count Binary Substrings
給一個字符串s,計算具有相同數字0和1的非空(連續)子字符串的數量,並且這些子字符串中的所有0和所有1都被連續分組。
發生多次的子字符串將被計數它們發生的次數。
Example 1:
Input: "00110011" Output: 6 Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01".
Notice that some of these substrings repeat and are counted the number of times they occur.
Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
Example 2:
Input: "10101" Output: 4 Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.第一次又超時了,看來一般在循環中加循環是個很不好的習慣,下面是錯誤示例:
class Solution(object):
def countBinarySubstrings(self, s):
"""
:type s: str
:rtype: int
"""
counts = 0
for i in range(len(s)-1):
if s[i] != s[i+1]:
count = 0
for j in range(min(i+1,len(s)-i-1)):
if s[i-j] == s[i] and s[i+1+j] == s[i+1]:
count += 1
else:
break
counts += count
return counts
以下是思考後的代碼:
class Solution(object):
def countBinarySubstrings(self, s):
"""
:type s: str
:rtype: int
"""
num={'0':0,'1':0}
count = 0
for i in range(len(s)-1):
if s[i] == s[i+1]:
num[s[i]] += 1
elif s[i] != s[i+1]:
num[s[i]] += 1
if num[s[i+1]] == 0:
pass
else:
count += min(num['0'],num['1'])
num[s[i+1]] = 0
num[s[-1]] += 1
count += min(num['0'],num['1'])
return count
大神的代碼:第一種方法思路和我一致,代碼簡潔一點
Here are some examples:
'00001111'
=>[4, 4]
=>min(4, 4)
=>4
'00110'
=>[2, 2, 1]
=>min(2, 2) + min(2, 1)
=>3
'10101'
=>[1, 1, 1, 1, 1]
=>4
class Solution(object):
def countBinarySubstrings(self, s):
chunks, consecutive, res = [], 1, 0
for i in range(1, len(s)):
if s[i] == s[i - 1]:
consecutive += 1
else:
chunks.append(consecutive)
consecutive = 1
chunks.append(consecutive)
for i in range(1, len(chunks)):
res += min(chunks[i], chunks[i - 1])
return res
An alternative way is to find the positions where the bits flip and we can derive the chunks from the positions of the flips.
class Solution(object):
def countBinarySubstrings(self, s):
flips, res = [0], 0
for i in range(1, len(s)):
if s[i] != s[i - 1]:
flips.append(i)
flips.append(len(s))
chunks = [a - b for (a, b) in zip(flips[1:], flips)]
for i in range(1, len(chunks)):
res += min(chunks[i], chunks[i - 1])
return res
A compressed 3-liner version of the above will look like this:
class Solution(object):
def countBinarySubstrings(self, s):
flips = [0] + [i for i in range(1, len(s)) if s[i] != s[i - 1]] + [len(s)]
chunks = [a - b for (a, b) in zip(flips[1:], flips)]
return sum(min(a, b) for a, b in zip(chunks, chunks[1:]))
另一個大大神:思路清晰
First, I count the number of 1 or 0 grouped consecutively.
For example "0110001111" will be [1, 2, 3, 4]
.
Second, for any possible substrings with 1 and 0 grouped consecutively, the number of valid substring will be the minimum number of 0 and 1.
For example "0001111", will be min(3, 4) = 3
, ("01",
"0011", "000111"
)
def countBinarySubstrings(self, s):
s = map(len, s.replace('01', '0 1').replace('10', '1 0').split())
return sum(min(a, b) for a, b in zip(s, s[1:]))
690. Employee Importance
[1,5,[2,3]]分別代表職員id,重要值和其下屬id,給定所有職工信息與一個id,求這個id的職工重要值和其所有下屬重要值之和
Example 1:
Input: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1 Output: 11 Explanation: Employee 1 has importance value 5, and he has two direct subordinates: employee 2 and employee 3. They both have importa奇怪的是,我第一份代碼在我自己環境下能跑,在leetcode裏卻會報錯
"""
# Employee info
class Employee(object):
def __init__(self, id, importance, subordinates):
# It's the unique id of each node.
# unique id of this employee
self.id = id
# the importance value of this employee
self.importance = importance
# the id of direct subordinates
self.subordinates = subordinates
"""
class Solution(object):
def getImportance(self, employees, id):
"""
:type employees: Employee
:type id: int
:rtype: int
"""
def findid(employees, id):
for i in employees:
if i[0] == id: #TypeError: 'Employee' object does not support indexing
return i
ans = findid(employees, id)[1]
for j in findid(employees, id)[2]:
ans += findid(employees, j)[1]
return ans
仔細看了代碼前一段,發現可能emoployees裏包含的是它定義的Employee類,不是list類,稍微改一下就好了,感慨小白基礎TT,不過確實這樣分類更好用,代碼也更易懂 def getImportance(self, employees, id):
"""
:type employees: Employee
:type id: int
:rtype: int
"""
def findid(employees, id):
for i in employees:
if i.id == id:
return i
ans = findid(employees, id).importance
for j in findid(employees, id).subordinates:
ans += findid(employees, j).importance
return ans
但是又報錯,發現要求是所有下屬,包括下下屬,需要用遞歸,繼續改:
"""
# Employee info
class Employee(object):
def __init__(self, id, importance, subordinates):
# It's the unique id of each node.
# unique id of this employee
self.id = id
# the importance value of this employee
self.importance = importance
# the id of direct subordinates
self.subordinates = subordinates
"""
class Solution(object):
def getImportance(self, employees, id):
"""
:type employees: Employee
:type id: int
:rtype: int
"""
def findid(employees, id):
for i in employees:
if i.id == id:
return i
if findid(employees, id).subordinates == []:
return findid(employees, id).importance
else:
ans = findid(employees, id).importance
for sub in findid(employees, id).subordinates:
ans += self.getImportance(employees,sub)
return ans
大神的代碼:我決定看一遍樹
Simply convert the employees array/list into a map for easy lookup and then do a DFS traversal from the "root" employee node.
By Yang Shun
class Solution(object):
def getImportance(self, employees, id):
"""
:type employees: Employee
:type id: int
:rtype: int
"""
# Time: O(n)
# Space: O(n)
emps = {employee.id: employee for employee in employees}
dfs = lambda id: sum([dfs(sub_id) for sub_id in emps[id].subordinates]) + emps[id].importance
return dfs(id)
If you wanna make it more readable, it is 5-lines:
class Solution(object):
def getImportance(self, employees, id):
"""
:type employees: Employee
:type id: int
:rtype: int
"""
# Time: O(n)
# Space: O(n)
emps = {employee.id: employee for employee in employees}
def dfs(id):
subordinates_importance = sum([dfs(sub_id) for sub_id in emps[id].subordinates])
return subordinates_importance + emps[id].importance
return dfs(id)
695. Max Area of Island
求最大島嶼面積,上下相連,斜着不相連
Example 1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,0,0,0,0,0,0,1,1,0,0,0,0]]Given the above grid, return
6
.
Note the answer is not 11, because the island must be connected 4-directionally.
Example 2:
[[0,0,0,0,0,0,0,0]]Given the above grid, return
0
.我的代碼:想了我好久,今天一天都沒怎麼學別的了TT
class Solution(object):
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
def cal_point(grid,x,y,lists,around):
if x != 0 and grid[y][x-1] == 1 and [x-1,y] not in lists:
lists.append([x-1,y])
around.append([x-1,y])
if x != len(grid[0])-1 and grid[y][x+1] == 1 and [x+1,y] not in lists:
lists.append([x+1,y])
around.append([x+1,y])
if y != 0 and grid[y-1][x] == 1 and [x,y-1] not in lists:
lists.append([x,y-1])
around.append([x,y-1])
if y !=len(grid)-1 and grid[y+1][x] == 1 and [x,y+1] not in lists:
lists.append([x,y+1])
around.append([x,y+1])
return lists,around
def cal_area(grid,x,y):
lists,around = cal_point(grid,x,y,[[x,y]],[])
while True:
if around == []:
return lists,len(lists)
else:
lists,around = cal_point(grid,around[0][0],around[0][1],lists,around)
around.pop(0)
temp = []
ans = 0
for y in range(len(grid)):
for x in range(len(grid[0])):
if grid[y][x] == 1 and [x,y] not in temp:
lists , lens = cal_area(grid,x,y)
print(lists)
temp += lists
ans = max(ans,lens)
return ans
大神的代碼,這個真的可以看出差距 def maxAreaOfIsland(self, grid):
m, n = len(grid), len(grid[0])
def dfs(i, j):
if 0 <= i < m and 0 <= j < n and grid[i][j]:
grid[i][j] = 0
return 1 + dfs(i - 1, j) + dfs(i, j + 1) + dfs(i + 1, j) + dfs(i, j - 1)
return 0
areas = [dfs(i, j) for i in range(m) for j in range(n) if grid[i][j]]
return max(areas) if areas else 0
520. Detect Capital
判別字符大小寫是否正確,用正則表達式比較簡單,廖雪峯的教程:
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832260566c26442c671fa489ebc6fe85badda25cd000
Example 1:
Input: "USA" Output: True
Example 2:
Input: "FlaG" Output: False我的代碼:
import re
class Solution(object):
def detectCapitalUse(self, word):
"""
:type word: str
:rtype: bool
"""
if re.match(r'^[A-Z]+$|^[a-z]+$|^[A-Z][a-z]+$', word):
return True
else:
return False
大神的代碼:原來python還有這樣的函數!
def detectCapitalUse(self, word):
return word.isupper() or word.islower() or word.istitle()
389. Find the Difference
給出一個字符串s,打亂並加入一個字符成爲字符串t,找出加入的新字符
Example:
Input: s = "abcd" t = "abcde" Output: e Explanation: 'e' is the letter that was added.我的代碼:開始以爲新加的字符不可以重複,結果來個‘aa'的測試,那麼進行生成列表排序相對比就好了
class Solution(object):
def findTheDifference(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
list_s = [i for i in s]
list_t = [j for j in t]
list_s.sort()
list_t.sort() #這裏幾步可以用sorted(s)代替
for i in range(len(s)):
if list_s[i] != list_t[i]:
return list_t[i]
return list_t[-1]
大神的代碼:
Using XOR: 異或真的是個很有用的東西,先把每個字符通過ord換成獨一的數字,每個進行異或後就只剩下多的那個了
class Solution(object):
def findTheDifference(self, s, t):
return chr(reduce(operator.xor, map(ord, s + t)))
Using collections.Counter()
:這個collections需要導入,可以參考廖雪峯的教程:
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001411031239400f7181f65f33a4623bc42276a605debf6000
class Solution(object):
def findTheDifference(self, s, t):
return list((collections.Counter(t) - collections.Counter(s)))[0]
A 2-liner here using sorted()
:
class Solution(object):
def findTheDifference(self, s, t):
s, t = sorted(s), sorted(t)
return t[-1] if s == t[:-1] else [x[1] for x in zip(s, t) if x[0] != x[1]][0]
258. Add Digits
將輸入的數字按位相加,反覆至結果爲一位數
For example:
Given num = 38
, the process is like: 3
+ 8 = 11
, 1 + 1 = 2
. Since 2
has
only one digit, return it.
class Solution(object):
def addDigits(self, num):
"""
:type num: int
:rtype: int
"""
def numsum(n):
return reduce(lambda x,y:x+y,[int(i) for i in str(n)])
while num > 9:
num = numsum(num)
return num
大神的代碼:用了一個巧妙的辦法:
this method depends on the truth:
N=(a[0] * 1 + a[1] * 10 + ...a[n] * 10 ^n),and a[0]...a[n] are all between [0,9]
we set M = a[0] + a[1] + ..a[n]
and another truth is that:
1 % 9 = 1
10 % 9 = 1
100 % 9 = 1
so N % 9 = a[0] + a[1] + ..a[n]
means N % 9 = M
so N = M (% 9)
as 9 % 9 = 0,so we can make (n - 1) % 9 + 1 to help us solve the problem when n is 9.as N is 9, ( 9 - 1) % 9 + 1 = 9
class Solution(object):
def addDigits(self, num):
"""
:type num: int
:rtype: int
"""
if num == 0 : return 0
else:return (num - 1) % 9 + 1
448. Find All Numbers Disappeared in an Array
給一個由n個數字組成的序列(1<=數字<=n),其中有些數字出現2次,那麼1~n中會有數字缺失,找出這些缺失的數字,要求複雜度O(n)
Example:
Input: [4,3,2,7,8,2,3,1] Output: [5,6]我的代碼:知道用set就能通過了
class Solution(object):
def findDisappearedNumbers(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
set1 = set(nums)
set2 = set([i+1 for i in range(len(nums))])
return list(set2-set1)
其他思路:
class Solution(object):
def findDisappearedNumbers(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
# For each number i in nums,
# we mark the number that i points as negative.
# Then we filter the list, get all the indexes
# who points to a positive number
for i in xrange(len(nums)):
index = abs(nums[i]) - 1
nums[index] = - abs(nums[index])
return [i + 1 for i in range(len(nums)) if nums[i] > 0]