Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
400a2e5
init & 26 && 189
lection Jun 4, 2019
6800fc3
update 189
lection Jun 4, 2019
a9a0c7f
add 189 v2 反转法
lection Jun 4, 2019
58e7c4a
189 简化最后反转代码
lection Jun 4, 2019
5599aac
lc_322 回溯+缓存的做法
lection Jun 5, 2019
90d2f87
优化 189 最大公约数方法的代码细节
lection Jun 5, 2019
d4a0929
补充一些注释
lection Jun 5, 2019
04d88b9
21 合并有序链表
lection Jun 5, 2019
3ee6c42
优化代码 当两个链表中有一个为空时 另一个直接接在结果链表即可
lection Jun 5, 2019
da35141
21 增加对于一开始就有空链表的情况处理
lection Jun 5, 2019
2a73e2b
21 增加一个更简短的递归的方法 但是确实可能存在递归调用过多的问题
lection Jun 5, 2019
3f07ff9
修改test文件名
lection Jun 5, 2019
3a7757d
88 从后向前排序实现
lection Jun 5, 2019
5de4ffe
24 链表 增加循环与递归两种解法
lection Jun 5, 2019
869036c
15 用一种似乎很丑陋的方式完成了
lection Jun 5, 2019
0048433
15 性能上优化,进行更多剪枝 加入网上5行答案进行参考
lection Jun 5, 2019
9ca3c96
15 进一步调整代码 优化剪枝 1120 ms 64.83%
lection Jun 6, 2019
fb6f696
189 优化代码 加入更python的数据交换写法
lection Jun 7, 2019
5b929a8
21 用更python的方式简化代码
lection Jun 7, 2019
128f7ee
88 非原地代码优化至1行
lection Jun 7, 2019
b2138fa
88 略微优化循环代码
lection Jun 7, 2019
bcae24a
优化88 循环代码
lection Jun 7, 2019
9791edc
24 使用哨兵和python交换变量语法进一步简化代码
lection Jun 7, 2019
5bf86b2
15 进一步优化剪枝 打败92%
lection Jun 7, 2019
5f43ff8
49 & 242 比较简单
lection Jun 7, 2019
a462329
1047
lection Jun 8, 2019
4bfaead
1021 & 1047
lection Jun 8, 2019
54e7c4d
add 441 可惜超时了
lection Jun 9, 2019
b5d90ca
104 && 236
lection Jun 9, 2019
94ea332
优化 15 的代码细节
lection Jun 9, 2019
5bd993c
add 101
lection Jun 9, 2019
ac139cb
add simple bs
lection Jun 10, 2019
0935325
rename file name
lection Jun 10, 2019
5786807
add bs_first 调试代码
lection Jun 10, 2019
56a3219
先用极其丑陋的代码实现一下726 有待优化
lection Jun 11, 2019
a8a78b6
删掉部分冗余代码
lection Jun 12, 2019
98ad2d5
代码细节调整
lection Jun 12, 2019
845f675
726 加入递归版本
lection Jun 12, 2019
0d77912
297 递归实现 超时
lection Jun 12, 2019
09148e3
297 我完全理解错了
lection Jun 12, 2019
192c6bd
总算是整对了
lection Jun 12, 2019
9c2212d
297 优化速度 144ms 打败93%
lection Jun 12, 2019
15c734a
297 微调优化速度
lection Jun 12, 2019
099cfd1
315 二分查找
lection Jun 13, 2019
8332dfe
692 我写的这么烂居然通过了……还打败了 98% 97%
lection Jun 13, 2019
452b546
3 O(2n) 这个题貌似有点儿简单,搞的我都有点儿膨胀了
lection Jun 14, 2019
b6c7dce
10 不行,我真的膨胀了。bfs的题连测试都懒的写了……
lection Jun 14, 2019
75448af
103 我真的膨胀了
lection Jun 14, 2019
9fbe027
101 嗯,换了个非递归的打法
lection Jun 14, 2019
f1a1ac0
98 使用中序遍历 和一个丑陋的递归子问题的方式实现
lection Jun 14, 2019
75651e5
加入一个优雅的递归代码 学习了
lection Jun 14, 2019
e30b45d
938
lection Jun 15, 2019
57bd842
220 初步实现 非常繁琐 有待优化
lection Jun 15, 2019
28c14d5
汗,暴力的效率还挺高的
lection Jun 15, 2019
ad49511
220 增加暴力破解和高人让人震惊的解法
lection Jun 15, 2019
e88ad04
优化315
lection Jun 17, 2019
91c04d4
242
lection Jun 17, 2019
5dd42a2
1 resolve
lection Jun 17, 2019
2287d8d
111 广度 + 深度剪枝
lection Jun 17, 2019
1a3415b
235
lection Jun 18, 2019
3260b7e
738 非递归
lection Jun 18, 2019
a1c79f5
783 优化非递归中序遍历代码
lection Jun 18, 2019
e705bd0
783 递归实现
lection Jun 18, 2019
7a25ebc
783 加入另一种非递归的中序遍历写法
lection Jun 18, 2019
0b56a7b
257
lection Jun 18, 2019
01229f6
295 最大最小堆实现中位数
lection Jun 19, 2019
29376bc
210 207
lection Jun 20, 2019
1c11ba2
210 dfs实现
lection Jun 21, 2019
cfa8c97
329 dfs+cache 我又要膨胀了,hard问题一条过……
lection Jun 21, 2019
ae535ba
优化拓扑排序
lection Jun 21, 2019
fb89d2e
529初步实现 但是代码有点儿繁琐 两次迭代周边八个节点,不知道能否简化
lection Jun 22, 2019
70af42f
529 略微优化一下
lection Jun 22, 2019
aaf20ee
127 dfs没做出来,始终超时。bfs反倒是比较容易。
lection Jun 22, 2019
94f68b6
103 优化实现
lection Jun 22, 2019
e498d78
310 暴力超时 叶子剪出 计数器三种方式
lection Jun 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Week_01/id_3/NOTE.md
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
# 学习笔记

## 小技巧
python的数组下标访问比hash快多了

l1, l2 = l2, l1
这个语法不但简单,而且思路其实适用于任何语言。
两个变量没有顺序要求,我们可以通过预处理的方式,强制变成有先后关系,这就避免了维护一个中间标量的尴尬

python的异或实现 bool(n1) != bool(n2) js也可以参考


DP 子问题有最优解 -> 全局最优解 找到最优子结构即可向上递推
递归 可以遍历所有解,这个是DP做不到的
54 changes: 54 additions & 0 deletions Week_01/id_3/array/15/LeetCode_15_3_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
def three_sum(nums):
r = []
if not nums or len(nums) < 3:
return r

cache = {}
dset = set()

new_nums = []

for n in nums:
count = 1 + cache.get(n, 0)
cache[n] = count
if n and count <= 2:
new_nums.append(n)

zero_count = cache.get(0, 0)
if zero_count >= 3:
r.append([0, 0, 0])

if zero_count > 0:
new_nums.append(0)

nums = new_nums
nums.sort()

length = len(nums)
for i in range(length):
n1 = nums[i]
# n1 >= 0 时说明已经遍历把有效的数据都进行遍历,继续遍历已经发生重复
if n1 >= 0:
break
for j in range(i+1, length):
n2 = nums[j]
if n1 == 0 and n2 == 0 and cache[0] < 3:
continue
s = -(n1 + n2)

# 迭代顺序是从小到大的
# 当-sum(n1,n2)的结果小于n2时 说明已经迭代出现了重复 -sum必然在之前已经迭代过
if s < n2:
break

if (s == n1 or s == n2) and cache.get(s, 0) == 1:
continue

if cache.get(s, 0):
arr = [n1, n2, s]
ds = '%s,%s' % (n1, n2)
if ds not in dset:
dset.add(ds)
r.append(arr)

return r
6 changes: 6 additions & 0 deletions Week_01/id_3/array/15/LeetCode_15_3_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def three_sum(nums):
nums, r = sorted(nums), set()
for i in [i for i in range(len(nums)-2) if i < 1 or nums[i] > nums[i-1]]:
d = {-nums[i]-n: j for j, n in enumerate(nums[i + 1:])}
r.update([(nums[i], n, -nums[i]-n) for j, n in enumerate(nums[i+1:]) if n in d and d[n] > j])
return list(map(list, r))
24 changes: 24 additions & 0 deletions Week_01/id_3/array/15/test_15.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import lc_15_v1
import lc_15_v2

f = lc_15_v1.three_sum
# f = lc_15_v2.three_sum


def check(nums, r):
_r = f(nums)
print(_r, r, _r == r)


check([-1, 0, 1, 2, -1, -4],
[
[-1, 0, 1],
[-1, -1, 2]
])


check([0, 0], [])
check([0, 0, 0], [[0, 0, 0]])

check([-4, -2, -2, -2, 0, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6],
[[-4, -2, 6], [-4, 0, 4], [-4, 1, 3], [-4, 2, 2], [-2, -2, 4], [-2, 0, 2]])
27 changes: 27 additions & 0 deletions Week_01/id_3/array/189/LeetCode_189_3_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 最大公约数
# 每次数组挪动一步,挪动k次,毫无疑问是可以实现的,但是时间复杂度 O(kn) 是无法接受的
# 如果每次移动的是nums[i]和nums[i+k],很可能无法遍历所有数据,例如len(nums)==9 k==3,此时只会在0,3,6三个下标之间进行移动
# 根据规律总结 如len(nums)与k的最小公倍数 是每次进行k偏移交换的循环
# 也就是len(nums)与k的最大公约数gcd会是产生循环迭代的次数。例如len(nums)==9 k==3 gcd==3 下标每次偏移3,3次就会出现循环。
# 所以需要 len(nums)/gcd 次就可以交换所有的数据

import math


def rotate(nums, k):
if not nums:
return

length = len(nums)
k = k % length

if not k:
return

gcd = math.gcd(length, k)

for offset in range(gcd):
tmp = nums[offset]
for i in range(1, int(length/gcd) + 1):
index = (i*k + offset) % length
nums[index], tmp = tmp, nums[index]
24 changes: 24 additions & 0 deletions Week_01/id_3/array/189/LeetCode_189_3_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 交换法
# 1,2,3,4,5,6,7 进行3位置的移动 等价于 list[0:4]+list[0:3] 两段数据的位置交换
# 位置交换的原地极简方案就是两次反转 [1,2,3,4,5,6,7] 反转0:4-> [4,3,2,1,5,6,7] 反转4:7-> [4,3,2,1,7,6,5] 全部反转-> [5,6,7,1,2,3,4]


def rotate(nums, k):
if not nums:
return

length = len(nums)
if length == 1:
return

k = k % length

tail = length - k - 1
for i in range(int((length-k)/2)):
nums[i], nums[tail-i] = nums[tail-i], nums[i]

tail = -k
for i in range(int(k/2)):
nums[-i-1], nums[tail+i] = nums[tail+i], nums[-i-1]

nums.reverse()
24 changes: 24 additions & 0 deletions Week_01/id_3/array/189/test_189.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import lc_189_v1
import lc_189_v2

# f = lc_189_v1.rotate
f = lc_189_v2.rotate


def check(params, k, arr):
_p = list(params)
f(params, k)
print(_p, params == arr)


check([1, 2, 3, 4, 5, 6, 7], 3, [5, 6, 7, 1, 2, 3, 4])
check([1, 2, 3, 4, 5, 6], 3, [4, 5, 6, 1, 2, 3])
check([1, 2, 3], 7, [3, 1, 2])
check([-1], 2, [-1])
check(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54],
45,
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 1, 2, 3, 4, 5, 6, 7, 8, 9]
)
12 changes: 12 additions & 0 deletions Week_01/id_3/array/26/LeetCode_26_3_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
def remove_duplicates(nums):
if not nums:
return 0

i = 1
cur = nums[0]
for n in nums:
if n != cur:
nums[i] = cur = n
i += 1

return i
12 changes: 12 additions & 0 deletions Week_01/id_3/array/26/test_26.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import lc_26_v1

f = lc_26_v1.remove_duplicates


def check(params, length, arr):
_p = list(params)
print(_p, f(params) == length and params[:length] == arr)


check([], 0, [])
check([1, 1, 2, 3], 3, [1, 2, 3])
16 changes: 16 additions & 0 deletions Week_01/id_3/array/88/LeetCode_88_3_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# nums1 m -> m+n 位置是剩余空间 如果按从小到大排序会出现复杂的冲突
# 而从大到小排列, 最大的元素移动到剩余空间的末端,则可以避免出现冲突


def merge(nums1, m, nums2, n):
tail = m + n
for i in range(tail):
if n == 0:
break
tail -= 1
if m > 0 and nums1[m-1] > nums2[n-1]:
m -= 1
nums1[tail] = nums1[m]
else:
n -= 1
nums1[tail] = nums2[n]
5 changes: 5 additions & 0 deletions Week_01/id_3/array/88/LeetCode_88_3_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 题目并未要求原地排序 所以弄个简单的


def merge(nums1, m, nums2, n):
nums1[:m+n] = sorted(nums1[:m] + nums2[:n])
13 changes: 13 additions & 0 deletions Week_01/id_3/array/88/test_88.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import lc_88_v1
import lc_88_v2

f = lc_88_v1.merge
# f = lc_88_v2.merge


def check(nums1, m, nums2, n, r):
f(nums1, m, nums2, n)
print(nums1, nums1 == r)


check([1, 2, 3, 0, 0, 0], 3, [2, 5, 6], 3, [1, 2, 2, 3, 5, 6])
10 changes: 10 additions & 0 deletions Week_01/id_3/bs/441/LeetCode_441_3_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def arrange_coins(n):
if n <= 0:
return 0
s = 0
k = 0
while s <= n:
k += 1
s += k

return k - 1
16 changes: 16 additions & 0 deletions Week_01/id_3/bs/441/LeetCode_441_3_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 此题超时了 有待用二分优化


def arrange_coins(n):
if n <= 0:
return 0
k = 1

while True:
s = int(((1 + k) * k)/2)
print(s, k)
if s == n:
return k
if s > n:
return k - 1
k += 1
15 changes: 15 additions & 0 deletions Week_01/id_3/bs/441/test_441.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import lc_441_v1
import lc_441_v2

# f = lc_441_v1.arrange_coins
f = lc_441_v2.arrange_coins


def check(n, r):
_r = f(n)
print(_r, r, _r == r)


check(5, 2)
check(8, 3)
check(2146533481, 65521)
90 changes: 90 additions & 0 deletions Week_01/id_3/bs/bs_basis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
def bs(nums, x):
if not nums:
return -1
length = len(nums)
low = 0
high = length - 1
while low <= high:
mid = low + int((high - low)/2)
v = nums[mid]
if v == x:
return mid
if v > x:
high = mid - 1
else:
low = mid + 1

return -1


def bs_first(nums, x):
if not nums:
return -1
length = len(nums)
low = 0
high = length - 1
while low <= high:
mid = low + int((high - low)/2)
v = nums[mid]
if v >= x:
high = mid - 1
else:
low = mid + 1

if low < length and nums[low] == x:
return low

return -1


def bs_last(nums, x):
low = 0
high = len(nums) - 1
while low <= high:
mid = low + (high - low)//2
v = nums[mid]
if v > x:
high = mid - 1
else:
low = mid + 1
if high >= 0 and nums[high] == x:
return high
return -1


def bs_gte(nums, x):
low = 0
high = len(nums) - 1
while low <= high:
mid = low + (high - low)//2
v = nums[mid]
if v >= x:
high = mid - 1
else:
low = mid + 1

return low


# print(bs([8, 11, 19, 23, 27, 33, 45, 55, 67, 98], 19) == 2)
# print(bs([8, 11, 19, 23, 27, 33, 45, 55, 67, 98], 33) == 5)
# print(bs([8, 11, 19, 23, 27, 33, 45, 55, 67, 98], 18) == -1)
# print(bs([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 19) == 4)
#
# print(bs_first([8, 8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 11) == 3)
# print(bs_first([8, 8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 8) == 0)
# print(bs_first([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 18) == -1)
# print(bs_first([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 188) == -1)
# print(bs_first([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 1) == -1)

print(bs_last([8, 8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 11) == 4)
print(bs_last([8, 8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 8) == 2)
print(bs_last([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 18) == -1)
print(bs_last([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 188) == -1)
print(bs_last([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 1) == -1)

# print(bs_gte([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 17) == 4)
# print(bs_gte([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 19) == 4)
# print(bs_gte([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 100) == 12)
# print(bs_gte([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 8) == 0)
# print(bs_gte([8, 8, 11, 11, 19, 23, 27, 33, 45, 55, 67, 98], 7) == 0)
16 changes: 16 additions & 0 deletions Week_01/id_3/hash/242/LeetCode_242_3_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
def is_anagram(s, t):
if len(s) != len(t):
return False

arr = [0] * 26
m = ord('a')
for c in s:
arr[ord(c) % m] += 1

for c in t:
i = ord(c) % m
if arr[i] == 0:
return False
arr[i] -= 1

return True
Loading