目錄
2. 給定一個二維數組,其每一行從左到右遞增排序,從上到下也是遞增排序。給定一個數,判斷這個數是否在該二維數組中。
5. 第n項斐波那契數列; 矩形覆蓋, n 個 2*1 的小矩形無重疊地覆蓋一個 2*n 的大矩形,總共有多少種方法?; 跳臺階
6. 複雜版跳臺階,對於n層臺階,一個青蛙可以一次跳1-n步,有多少種跳法?
判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向上下左右移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子。
Excel表, A表示第一列, AA表示第27列,AB表示第28列,根據表的字符串索引轉換成數字
15. 輸入兩個整數m,n,判斷二進制最少改變多少位能得m->n
如輸入 a = '3[ab]acc',則輸出'abababacc'
輸入[1,2,3],輸出[[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
輸入'abc',輸出['abc', 'acb', 'bac', 'bca', 'cab', 'cba']。
請實現一個函數用來匹配包括 '.' 和 '*' 的正則表達式。模式中的字符 '.' 表示任意一個字符,而 '*' 表示它前面的字符可以出現任意次(包含 0 次)。
28. 火柴拼成的數字,從一個數移動一根給另外一個數(只能移動一次),移動後最大值?
29. 股票可以有一次買入和一次賣出,買入必須在前。求最大收益。
30. 圓圈中最後的小孩,n個小孩,第0個開始數到m,無放回出列,再從下一個開始數,最後小孩是都在時候第幾個?
1. 找到數組中重複數字(字符),返回出現頻次最多
# 時間複雜度O(N), 空間複雜度O(1)
class Solution(object):
def find_duplicated(self, a):
res = 0
for i in a:
n = 1 << i-0
if (res | n) == res:
return i
else:
res |= n
return res
# 字典方法,時間複雜度O(N), 空間複雜度O(N)
def maxf(x):
a = dict()
max = 0
for i in x:
tem = str(i)
a[tem] = a.get(tem,0) + 1
if max < a[tem]:
max = a[tem]
return max
2. 給定一個二維數組,其每一行從左到右遞增排序,從上到下也是遞增排序。給定一個數,判斷這個數是否在該二維數組中。
class Solution(object):
def find_in_matrix(self, f, a):
row, column = a.shape
for i in range(row):
# 最後一列大於還是小於
if f > a[i,column-1]:
continue
else:
# 不斷左移對比
while column-1 >= 0:
if f == a[i, column-1]:
return True
else:
column -= 1
return False
3. 從尾到頭打印鏈表
class Solution(object):
def reverse_print(self, list_node):
res = []
while list_node:
res.append(0, list_node.val)
list_node = list_node.next
return res
4. 用兩個棧實現隊列
class Solution(object):
def __init__(self):
self.s1 = []
self.s2 = []
def pop(self):
return self.s2.pop()
def push(self, a):
for i in a:
self.s1.append(i)
while len(self.s1):
self.s2.append(self.s1.pop())
5. 第n項斐波那契數列; 矩形覆蓋, n 個 2*1 的小矩形無重疊地覆蓋一個 2*n 的大矩形,總共有多少種方法?; 跳臺階
# 遞歸
class Solution(object):
def find_fibo(self, a):
if a == 0:
return 0
elif a == 1:
return 1
else:
return self.find_fibo(a-1) + self.find_fibo(a-2)
# 動態規劃 O(N) 最優解
class Solution(object):
def find_fibo(self, a):
min1 = 0
min2 = 1
if a == 0:
return 0
elif a == 1:
return 1
else:
for i in range(2, a+1):
a = min2
min2 = min1 + min2
min1 = a
return min2
6. 複雜版跳臺階,對於n層臺階,一個青蛙可以一次跳1-n步,有多少種跳法?
# f(n) = f(n-1) + f(n-2) + ... + f(0)
# f(n-1) = f(n-2) + f(n-3) + ... + f(0)
# f(n) - f(n-1) = f(n-1) 等比
class Solution(object):
def jump_num(self, a):
if a == 0:
return 0
return 2**(a-1)
7. 二分查找
# 時間複雜度O(log2(N))
class Solution(object):
def main(self, a, b):
l = 0
h = len(a) - 1
while l <= h:
m = (h + l) // 2
if a[l] < b and a[m] > b:
h = m-1
elif a[h] > b and a[m] < b:
l = m+1
elif a[m] == b:
return m
else:
return -1
8. 有序旋轉數組最小數字查找
# 時間複雜度O(log2(N)
class Solution(object):
def find_min(self, a):
if len(a) == 1:
return a[0]
v = a[0]
l = 0
h = len(a) - 1
while l < h:
mid = (h + l) // 2
if a[l] <= a[mid]:
if v > a[l]:
v = a[l]
l = mid
else:
if v > a[mid]:
v = a[mid]
h = mid - 1
return v
9. 機器人運動範圍
# a*b矩陣,當a和b每位數之和sum((12,34),sum = 1+2+3+4)<=k時允許進入該格子,統計路徑最多能走多遠,這個解決的比原題要難一些。
class Solution(object):
def __init__(self):
self.rows = None
self.columns = None
def check_boundry(self, k, x, y):
c = 0
while x > 0:
c += x % 10
x = x // 10
while y > 0:
c += y % 10
y = y // 10
return True if k >= c else False
def max_move(self, mat, coordinate):
x, y = coordinate[0], coordinate[1]
if x < 0 or x >= self.rows:
return 0
elif y < 0 or y >= self.columns:
return 0
if mat[x, y] == 1:
mat[x, y] = 0
return 1 + max(self.max_move(mat, [x-1, y]), self.max_move(mat, [x+1, y]),
self.max_move(mat, [x, y-1]), self.max_move(mat, [x, y+1]))
else:
return 0
def main(self, k, m, n):
if k<0 or m<=0 or n<=0:
return 0
self.rows, self.columns = m, n
mat = np.mat(np.ones((m, n)))
# 生成矩陣,指明哪些能走,哪些不能走
for i in range(self.rows):
for j in range(self.columns):
if not self.check_boundry(k, i, j):
mat[i, j] = 0
return self.max_move(mat, [0, 0])
10. 剪繩子
# 一根長度爲n的繩子,剪成m段,n,m >1且爲整數,求子段長度最大乘積。貪婪算法
class Solution(object):
def maxproduct(self, a):
if a < 2:
return 0
elif a == 2:
return 1
elif a == 3:
return 2
elif a == 4:
return 4
elif a >= 5:
c = a // 3
r = a % 3
if r == 1:
return (3**(c-1)) * 4
else:
return (3**c) * r
11. 矩陣中的路徑是否存在
判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向上下左右移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子。
例如下面的矩陣包含了一條 bfce 路徑。
from numpy import matrix
class Solution(object):
def __init__(self):
self.rows = None
self.columns = None
def find_root(self, a, m):
self.rows, self.columns = m.shape
for i in range(self.rows):
for j in range(self.columns):
if self.find(m, [i, j], a):
return True
return False
def find(self, data, coordinate, a, ):
x, y = coordinate[0], coordinate[1]
if x < 0 or x >= self.rows:
return False
elif y < 0 or y >= self.columns:
return False
if data[x, y] == a[0]:
if len(a) == 1:
return True
data[x, y] = ''
return self.find(data, [x-1, y], a[1:]) | \
self.find(data, [x+1, y], a[1:]) | \
self.find(data, [x, y-1], a[1:]) | \
self.find(data, [x, y+1], a[1:])
else:
return False
# m = matrix([['a','b','c'],['d','e','f'],['g','h','i']])
# s = Solution()
# print(s.find_root('adefc', m))
12. 進制轉換問題
Excel表, A表示第一列, AA表示第27列,AB表示第28列,根據表的字符串索引轉換成數字
class Solution(object):
def find_column(self, a):
res = 0
l = len(a) - 1
for i, value in enumerate(a):
res += (26**(l-i)) * (ord(value) - ord('A') + 1)
return res
13. 二進制中1的個數
class Solution(object):
def find_one_num(self, a):
res = 0
while a > 0:
a = a & a-1
res += 1
return res
14. 一條語句判斷一個整數是不是2的整數次方
class Solution(object):
def whether_div_two(self, a):
return True if a & a-1 == 0 else False
15. 輸入兩個整數m,n,判斷二進制最少改變多少位能得m->n
先求異或,再統計異或結果1的個數
16. 字符串解壓縮
如輸入 a = '3[ab]acc',則輸出'abababacc'
class Solution(object):
def main(self, a):
res = ""
check_point_num = 0
check_point_str = ""
gate = 0
for i in a:
if i.isdigit():
check_point_num = int(i)
continue
elif i == "[":
gate = 1
continue
elif i == "]":
gate = 2
if gate == 1:
check_point_str += i
elif gate == 2:
res += check_point_str * check_point_num
gate = 0
check_point_num = 0
check_point_str = ""
elif gate == 0:
res += i
return res
17. O(1)時間刪除鏈表節點
class ListNode(object):
def __init__(self):
self.val = None
self.next = None
class Solution(object):
def main(self, head, delete):
if head is None or delete is None:
return None
if delete.next is not None:
next = delete.next
delete.val = next.val
delete.next = next.next
else:
if head is None:
head = None
else:
cur = head
while cur != delete:
cur = cur.next
cur.next = None
return head
18.尋找所有可能子集合
輸入[1,2,3],輸出[[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
class Solution(object):
def main(self, a):
res = self.find_subset(a)
for i in a:
res += [[i]]
res.append([])
return res
def find_subset(self, a):
if len(a) <= 1:
return []
# 把當前最長加進去
res = [a]
for i,v in enumerate(a):
# 用子集獲取最長串
for j in self.find_subset(a[0:i]+a[i+1:]):
if j not in res:
res.append(j)
return res
19. 輸出字符串所有可能排列組合
輸入'abc',輸出['abc', 'acb', 'bac', 'bca', 'cab', 'cba']。
class Solution(object):
def main(self, a):
res = []
if len(a) == 1:
return a
# 把每個都有機會放最前面
for i, v in enumerate(a):
for j in self.main(a[:i] + a[i+1:]):
res.append(v + j)
return res
20. 順時針打印長寬相等矩陣
class Solution(object):
def __init__(self):
self.rows = 0
self.columns = 0
def main(self, m):
self.rows, self.columns = m.shape
if self.rows == 1 and self.columns == 1:
return m[0, 0]
res = []
x1, y1 = 0, 0
x2, y2 = self.rows-1, self.columns-1
# 打印四個方向規律一樣,打印完一圈往裏走一圈
while x1 <= x2 and y1 <= y2:
if x1 == x2 and y1 == y2:
res.append(m[x1, y1])
break
for i in range(y1, y2+1):
res.append(m[x1, i])
for i in range(x1+1, x2+1):
res.append(m[i, y2])
for i in range(y1, y2)[::-1]:
res.append(m[x2, i])
for i in range(x1+1, x2)[::-1]:
res.append(m[i, y1])
x1 += 1
x2 -= 1
y1 += 1
y2 -= 1
return res
21. 找到數組中出現次數超過一半的數字
# 時間複雜度O(N), 空間複雜度O(1)
class Solution(object):
def main(self, a):
if len(a) == 1:
return a[0]
# 兩兩對衝
res = a[0]
num = 1
for i in range(1, len(a)):
if a[i] != res:
num -= 1
if num < 0:
res = a[i]
num = 1
else:
num += 1
return res
22. 數組中連續子數組最大和
# 初始設置sum爲0,遍歷數組往後加,遇到加之後小於0情況sum清零並且result記錄sum上次大於0的值。
# 時間複雜度O(N)
class Solution(object):
def main(self, a):
if len(a) == 1:
return max(a[0])
res = 0
tmp = 0
checkpoint = 0
for i in a:
if checkpoint == 0 and i <= 0:
continue
if i >= 0:
checkpoint += i
else:
if res < checkpoint:
res = checkpoint
if checkpoint + i <= 0:
checkpoint = 0
else:
checkpoint += i
return max(res, checkpoint)
23. 正則表達式匹配
請實現一個函數用來匹配包括 '.' 和 '*' 的正則表達式。模式中的字符 '.' 表示任意一個字符,而 '*' 表示它前面的字符可以出現任意次(包含 0 次)。
class Solution(object):
def main(self, a, pattern):
if len(pattern) == 0:
return ""
res = ""
pass_flag = False
for i, v in enumerate(a):
if res != "":
return res
for j, vv in enumerate(pattern):
if pass_flag:
pass_flag = False
continue
# pattern到頭
if j == len(pattern) - 1 and vv == "*":
while True:
if i < len(a) and res[-1] == a[i]:
res += a[i]
i += 1
else:
break
return res
# str到頭
if i >= len(a):
res = ""
break
if vv == ".":
res += a[i]
i += 1
elif vv == "*":
while True:
if i >= len(a):
res = ""
break
if res[-1] == a[i]:
res += a[i]
i += 1
else:
break
else:
if vv == a[i]:
res += a[i]
i += 1
else:
if pattern[j+1] == "*":
pass_flag = True
else:
res = ""
break
return res
24. 鏈表反轉
class Solution(object):
def main(self, a):
if a is None or a.next is None:
return a
next = a.next
a.next = None
b = self.main(next)
next.next = a
return b
25. 禮物最大價值
class Solution(object):
def main(self, m):
r, c = m.shape
if r * c == 0:
return 0
for i in range(r):
for j in range(c):
if i + j == 0:
continue
if i == 0:
m[0, j] += m[0, j-1]
elif j == 0:
m[i, 0] += m[i-1, 0]
else:
m[i, j] += max(m[i, j-1], m[i-1, j])
return m[r-1, c-1]
26. 和爲n的所有連續正數列
class Solution(object):
def main(self, m):
res = []
for i in range(1, m//2):
s = 0
j = i
while True:
if s < m:
s += i
i += 1
else:
if s == m:
res.append([x for x in range(j, i)])
break
return res
27. 去除字符串字符連續出現次數大於2的
# While每次都遍歷一遍字符串消除連續出現次數大於2的,直到有一次遍歷沒問題則跳出
class Solution(object):
def main(self, a):
while True:
checkpoint_v = ""
checkpoint_i = 0
counter = 0
break_flag = True
for v in a:
if v == checkpoint_v:
counter += 1
continue
if counter > 2:
a = a[:checkpoint_i] + a[checkpoint_i + counter:]
break_flag = False
else:
checkpoint_i = checkpoint_i + counter
checkpoint_v = v
counter = 1
if break_flag:
break
return a
28. 火柴拼成的數字,從一個數移動一根給另外一個數(只能移動一次),移動後最大值?
class Solution(object):
def __init__(self):
# 數字根數映射 & 根數對應最大數字映射
self.counter = {"0":6, "1":2, "2":5, "3":5, "4":4, "5":5, "6":6, "7":3, "8":7, "9": 6}
self.num_to_max_digit = {"2":"1", "3":"7", "4":"4", "5":"5", "6":"9", "7":"8"}
def replace_char(self, s, v, idx):
res = ""
for i in range(len(s)):
if i == idx:
res += v
else:
res += s[i]
return res
def main(self, a):
s = str(a)
if len(s) <= 1:
return a
max_value = a
for i in range(len(s)):
give_ = s[i]
if str(self.counter[give_] - 1) not in self.num_to_max_digit:
continue
give_after = self.num_to_max_digit[str(self.counter[give_] - 1)]
b = self.replace_char(s, give_after, i)
for j, receive_ in enumerate(b):
if j == i:
continue
if str(self.counter[receive_] + 1) not in self.num_to_max_digit:
continue
receive_after = self.num_to_max_digit[str(self.counter[receive_] + 1)]
c = self.replace_char(b, receive_after, j)
if int(c) > max_value:
max_value = int(c)
return max_value
29. 股票可以有一次買入和一次賣出,買入必須在前。求最大收益。
class Solution(object):
def main(self, n):
res = 0
for i in range(1, len(n)):
sell = n[i]
buy = min(n[:i])
profit = sell - buy
if profit > res:
res = profit
return res
30. 圓圈中最後的小孩,n個小孩,第0個開始數到m,無放回出列,再從下一個開始數,最後小孩是都在時候第幾個?
class Solution(object):
def main(self, n, m):
if n < 1:
return -1
children = [i for i in range(n)]
start = 1
while len(children) > 1:
final = m + start - 1
if final % len(children) == 0:
children.pop(-1)
start = 1
else:
start = final % len(children)
children.pop(start - 1)
return children[0]
31. n個篩子,求扔出去和爲s的概率
class Solution(object):
def main(self, n, s):
if n == 1 and s <= 6:
return 1
elif (n == 1 and s > 6) or (s < n):
return 0
return self.main(n-1, s-1) + self.main(n-1, s-2) \
+ self.main(n-1, s-3) + self.main(n-1, s-4) \
+ self.main(n-1, s-5) + self.main(n-1, s-6)
def result(self, n, s):
res = self.main(n, s)
return res/(6**n)
32. 滑動窗口最大值, 數組a,窗口大小爲k
class Solution(object):
def main(self, a, k):
if k > len(a):
return []
res = []
for i in range(0, len(a)-k+1):
res.append(max(a[i:i+k]))
return res
33. 和爲s兩個數字,有多組選積最小的
class Solution(object):
def main(self, l, s):
product = float('inf')
j = len(l) - 1
for i in range(len(l)):
if j <= 0:
break
if l[i] + l[j] < s:
continue
elif l[i] + l[j] == s:
p = l[i] * l[j]
if p < product:
product = p
else:
j -= 1
return product
34. 一個數組只出現過一次的數,其餘均兩次
class Solution(object):
def main(self, a):
res = 0
for i in a:
res ^= i
return res
35. 有序數組指定數出現次數
class Solution(object):
def main(self, a, v):
l = 0
r = len(a) - 1
count = 0
while l < r:
m = r // 2
if a[m] < v:
l = m
elif a[m] > v:
r = m
else:
l = m-1
r = m+1
count += 1
while True:
if (l < 0 and r >= len(a)) or (a[l] != v and a[r] != v):
break
if l >= 0 and a[l] == v:
count += 1
l -= 1
if r >= 0 and a[r] == v:
count += 1
r += 1
break
return count
36. 醜數
class Solution(object):
def main(self, n):
if n <= 6:
return n
i2, i3, i5 = 0, 0, 0
res = [1]
cur_num = 1
while cur_num < n:
min_value = min(res[i2]*2, res[i3]*3, res[i5]*5)
res.append(min_value)
while res[i2]*2 <= min_value:
i2 += 1
while res[i3]*3 <= min_value:
i3 += 1
while res[i5]*5 <= min_value:
i5 += 1
cur_num += 1
return res[-1]
21。數字序列某一位數字
數字以123456789101112...格式序列化到一個字符序列中,求任意n位對應的數字,13位對應1
思想:前9位長度9,前99位長度2*(99-9)+9,前999位長度3*(999-99)+99
a = input()
b = int(a)
if b <=9:
print(n)
p = 9
lenn = 2
L = 9
i = 99
while(L<b):
tem = L
lenn1 = lenn
p1 = p
L = lenn*(i-p)+ L
p = i
i = i*10 + 9
lenn = lenn+1
result = int((b-tem)/lenn1)+p1
if int((b-tem)%lenn1) == 0:
result = result%10
else:
chang = (b-tem)%lenn1
tem1 = list(str(result+1))
result = tem1[chang-1]
print(int(result))
22.找出數組中和爲s的任意兩數字
時間複雜度O(n*log2(n)+n)
# 堆排序或快排對a排序,時間複雜度O(N*log2(N))
def find(a,x):
l= 0
r = len(a)-1
while(l < r):
if a[l]+a[r] > x:
r = r - 1
if a[l]+a[r] < x:
l = l + 1
if a[l]+a[r] == x:
return a[l],a[r]
break