diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/01.\345\220\210\345\224\261\345\233\242.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/01.\345\220\210\345\224\261\345\233\242.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/01.\345\220\210\345\224\261\345\233\242.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/01.\345\220\210\345\224\261\345\233\242.py" index 0543116..633250b 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/01.\345\220\210\345\224\261\345\233\242.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/01.\345\220\210\345\224\261\345\233\242.py" @@ -1,15 +1,15 @@ -# 动态规划 -n = int(raw_input()) -stu = map(int, raw_input().split()) -k, d = map(int, raw_input().split()) -res_max = [[0]*k for _ in range(n)] -res_min = [[0]*k for _ in range(n)] -for i in range(n): - res_max[i][0] = stu[i] - res_min[i][0] = stu[i] -for j in range(1, k): - for i in range(n): - for p in range(i+1, min(i+d+1, n)): - res_max[p][j] = max(max(res_min[i][j-1]*stu[p], res_max[i][j-1]*stu[p]), res_max[p][j]) - res_min[p][j] = min(min(res_min[i][j-1]*stu[p], res_max[i][j-1]*stu[p]), res_min[p][j]) +# 动态规划 +n = int(raw_input()) +stu = map(int, raw_input().split()) +k, d = map(int, raw_input().split()) +res_max = [[0]*k for _ in range(n)] +res_min = [[0]*k for _ in range(n)] +for i in range(n): + res_max[i][0] = stu[i] + res_min[i][0] = stu[i] +for j in range(1, k): + for i in range(n): + for p in range(i+1, min(i+d+1, n)): + res_max[p][j] = max(max(res_min[i][j-1]*stu[p], res_max[i][j-1]*stu[p]), res_max[p][j]) + res_min[p][j] = min(min(res_min[i][j-1]*stu[p], res_max[i][j-1]*stu[p]), res_min[p][j]) print(max(res_max[i][k-1] for i in range(n))) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/02.\345\234\260\347\211\242\351\200\203\350\204\261.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/02.\345\234\260\347\211\242\351\200\203\350\204\261.py" similarity index 98% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/02.\345\234\260\347\211\242\351\200\203\350\204\261.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/02.\345\234\260\347\211\242\351\200\203\350\204\261.py" index 53d78ff..130f172 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/02.\345\234\260\347\211\242\351\200\203\350\204\261.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/02.\345\234\260\347\211\242\351\200\203\350\204\261.py" @@ -1,47 +1,47 @@ -''' -题意可以理解为:有没有可以通行的点,但牛牛到不了(输出-1)。如果没有这样的点,牛牛可能花费最多步数是多少。 -思路:计算地图里,每个点的最短到达步数。找到到不了的点,或者最短步数里步数最多的点。 -1. 创建3个矩阵,size都是n*m的。分别是地图矩阵 mm、步数矩阵 sm、到达矩阵 am。 -2. 设置初始点为第一轮的探索点,更新 sm 里初始点的最短步数为0,更新 am 里初始点的到达状态为1。 -3. 找到从探索点一步能到达的点,且这些点可以通行并没有到达过。更新这些点的 sm 和 am。并将这些点当作下一轮的探索点。 -4. 循环第3步,直到没有新一轮的探索点了。 -5. 从 sm 中可以得到正确答案。 -''' - -#coding=utf-8 -n, m = map(int, raw_input().split()) -map_matrix = [raw_input() for _ in range(n)] # 地图矩阵,'.' 表示可以通行的位置,'X' 表示不可通行的障碍 -x0, y0 = map(int, raw_input().split()) # 开始点的坐标 -k = int(raw_input()) # 共有k种行走方式 -alternative_steps = [map(int, raw_input().split()) for _ in range(k)] # 可以选择的行走方式 -step_matrix = [[-1]*m for _ in range(n)] # 步数矩阵,记录到达该点使用最短步数。初始是-1 -arrived_matrix = [[0]*m for _ in range(n)] # 到达矩阵,记录是否已经到达过该点。初始是0,表示没有到达过 -arrived_matrix[x0][y0] = 1 # 初始点修改为已到达的点 -step_matrix[x0][y0] = 0 # 初始点到达步数为0 -current_points = [[x0, y0]] # 第一轮所在的探索点(多个) -while len(current_points) > 0: # 如果当前探索点是0个,结束循环。 - next_points = [] # 下一轮的探索点(多个) - for point in current_points: - x, y = point[0], point[1] # 一个探索点 - for step in alternative_steps: - x_, y_ = x + step[0], y + step[1] # 该探索点一步能到达的点 - # 检查是否越界,该点是否可以通行,或者已经达到过 - if x_ < 0 or x_ >= n or y_ < 0 or y_ >= m or map_matrix[x_][y_] != '.' or arrived_matrix[x_][y_] == 1: - continue - step_matrix[x_][y_] = step_matrix[x][y] + 1 # 更新步数矩阵 - arrived_matrix[x_][y_] = 1 # 更新到达矩阵 - next_points.append([x_, y_]) # 该点添加到下一轮探索点里 - current_points = next_points -# 从步数矩阵中找到到不了的点,或者最大的步数,然后输出 -try: - max_step = 0 - for i in range(n): - for j in range(m): - step = step_matrix[i][j] - if step==-1 and map_matrix[i][j]=='.': - raise Exception - if step > max_step: - max_step = step - print(max_step) -except: +''' +题意可以理解为:有没有可以通行的点,但牛牛到不了(输出-1)。如果没有这样的点,牛牛可能花费最多步数是多少。 +思路:计算地图里,每个点的最短到达步数。找到到不了的点,或者最短步数里步数最多的点。 +1. 创建3个矩阵,size都是n*m的。分别是地图矩阵 mm、步数矩阵 sm、到达矩阵 am。 +2. 设置初始点为第一轮的探索点,更新 sm 里初始点的最短步数为0,更新 am 里初始点的到达状态为1。 +3. 找到从探索点一步能到达的点,且这些点可以通行并没有到达过。更新这些点的 sm 和 am。并将这些点当作下一轮的探索点。 +4. 循环第3步,直到没有新一轮的探索点了。 +5. 从 sm 中可以得到正确答案。 +''' + +#coding=utf-8 +n, m = map(int, raw_input().split()) +map_matrix = [raw_input() for _ in range(n)] # 地图矩阵,'.' 表示可以通行的位置,'X' 表示不可通行的障碍 +x0, y0 = map(int, raw_input().split()) # 开始点的坐标 +k = int(raw_input()) # 共有k种行走方式 +alternative_steps = [map(int, raw_input().split()) for _ in range(k)] # 可以选择的行走方式 +step_matrix = [[-1]*m for _ in range(n)] # 步数矩阵,记录到达该点使用最短步数。初始是-1 +arrived_matrix = [[0]*m for _ in range(n)] # 到达矩阵,记录是否已经到达过该点。初始是0,表示没有到达过 +arrived_matrix[x0][y0] = 1 # 初始点修改为已到达的点 +step_matrix[x0][y0] = 0 # 初始点到达步数为0 +current_points = [[x0, y0]] # 第一轮所在的探索点(多个) +while len(current_points) > 0: # 如果当前探索点是0个,结束循环。 + next_points = [] # 下一轮的探索点(多个) + for point in current_points: + x, y = point[0], point[1] # 一个探索点 + for step in alternative_steps: + x_, y_ = x + step[0], y + step[1] # 该探索点一步能到达的点 + # 检查是否越界,该点是否可以通行,或者已经达到过 + if x_ < 0 or x_ >= n or y_ < 0 or y_ >= m or map_matrix[x_][y_] != '.' or arrived_matrix[x_][y_] == 1: + continue + step_matrix[x_][y_] = step_matrix[x][y] + 1 # 更新步数矩阵 + arrived_matrix[x_][y_] = 1 # 更新到达矩阵 + next_points.append([x_, y_]) # 该点添加到下一轮探索点里 + current_points = next_points +# 从步数矩阵中找到到不了的点,或者最大的步数,然后输出 +try: + max_step = 0 + for i in range(n): + for j in range(m): + step = step_matrix[i][j] + if step==-1 and map_matrix[i][j]=='.': + raise Exception + if step > max_step: + max_step = step + print(max_step) +except: print(-1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/03.\344\270\213\345\216\250\346\210\277.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/03.\344\270\213\345\216\250\346\210\277.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/03.\344\270\213\345\216\250\346\210\277.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/03.\344\270\213\345\216\250\346\210\277.py" index 39c1a71..cac18d1 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/03.\344\270\213\345\216\250\346\210\277.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/03.\344\270\213\345\216\250\346\210\277.py" @@ -1,7 +1,7 @@ -# 每个字符串加到集合中去重 -import sys -s = set() -for line in sys.stdin: - for i in line.split(): - s.add(i) +# 每个字符串加到集合中去重 +import sys +s = set() +for line in sys.stdin: + for i in line.split(): + s.add(i) print(len(s)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/04.\345\210\206\347\224\260\345\234\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/04.\345\210\206\347\224\260\345\234\260.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/04.\345\210\206\347\224\260\345\234\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/04.\345\210\206\347\224\260\345\234\260.py" index 0d77465..4df6ec4 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/04.\345\210\206\347\224\260\345\234\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/04.\345\210\206\347\224\260\345\234\260.py" @@ -1,44 +1,44 @@ -n,m=map(int,raw_input().strip().split()) -matrix=[map(int,list(raw_input().strip())) for _ in range(n)] -sum_values = [[0]*(m+1) for i in range(n + 1)] -for i in range(1, n + 1): - for j in range(1, m + 1): - sum_values[i][j] += sum_values[i - 1][j] + sum_values[i][j - 1] - sum_values[i - 1][j - 1] + matrix[i-1][j-1] - -def calculate_sum(p1,p2): - x1,y1=p1 - x2,y2=p2 - a1,a2=sum_values[x1 - 1][y1 - 1],sum_values[x1 - 1][y2] - a3,a4=sum_values[x2][y1 - 1],sum_values[x2][y2] - value=a4-a3-a2+a1 - return value - -def check(mid): - for j1 in range(1, m - 2): - if calculate_sum((1,1),(n,j1)) < mid * 4: continue - for j2 in range(j1 + 1, m - 1): - if calculate_sum((1,j1+1),(n,j2)) < mid * 4: continue - for j3 in range(j2 + 1, m): - if calculate_sum((1,j2+1),(n,j3)) < mid * 4: continue - if calculate_sum((1,j3+1),(n,m)) < mid * 4: continue - pstart,row_count=1,0 - for pend in range(1, n + 1): - p1_list=[(pstart,1),(pstart,j1+1),(pstart,j2+1),(pstart,j3+1)] - p2_list=[(pend,j1),(pend,j2),(pend,j3),(pend,m)] - values=[calculate_sum(p1,p2) for p1,p2 in zip(p1_list,p2_list)] - if min(values) >= mid: - pstart=pend+1 - row_count+=1 - if row_count == 4:return True - return False - -l, r = 0, sum_values[n][m] -answer = 0 -while l <= r: - mid = (l + r) / 2 - if check(mid): - l = mid + 1 - answer = mid - else: - r = mid - 1 +n,m=map(int,raw_input().strip().split()) +matrix=[map(int,list(raw_input().strip())) for _ in range(n)] +sum_values = [[0]*(m+1) for i in range(n + 1)] +for i in range(1, n + 1): + for j in range(1, m + 1): + sum_values[i][j] += sum_values[i - 1][j] + sum_values[i][j - 1] - sum_values[i - 1][j - 1] + matrix[i-1][j-1] + +def calculate_sum(p1,p2): + x1,y1=p1 + x2,y2=p2 + a1,a2=sum_values[x1 - 1][y1 - 1],sum_values[x1 - 1][y2] + a3,a4=sum_values[x2][y1 - 1],sum_values[x2][y2] + value=a4-a3-a2+a1 + return value + +def check(mid): + for j1 in range(1, m - 2): + if calculate_sum((1,1),(n,j1)) < mid * 4: continue + for j2 in range(j1 + 1, m - 1): + if calculate_sum((1,j1+1),(n,j2)) < mid * 4: continue + for j3 in range(j2 + 1, m): + if calculate_sum((1,j2+1),(n,j3)) < mid * 4: continue + if calculate_sum((1,j3+1),(n,m)) < mid * 4: continue + pstart,row_count=1,0 + for pend in range(1, n + 1): + p1_list=[(pstart,1),(pstart,j1+1),(pstart,j2+1),(pstart,j3+1)] + p2_list=[(pend,j1),(pend,j2),(pend,j3),(pend,m)] + values=[calculate_sum(p1,p2) for p1,p2 in zip(p1_list,p2_list)] + if min(values) >= mid: + pstart=pend+1 + row_count+=1 + if row_count == 4:return True + return False + +l, r = 0, sum_values[n][m] +answer = 0 +while l <= r: + mid = (l + r) / 2 + if check(mid): + l = mid + 1 + answer = mid + else: + r = mid - 1 print(answer) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/05.\345\210\206\350\213\271\346\236\234.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/05.\345\210\206\350\213\271\346\236\234.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/05.\345\210\206\350\213\271\346\236\234.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/05.\345\210\206\350\213\271\346\236\234.py" index 8e41523..f10535d 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/05.\345\210\206\350\213\271\346\236\234.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/05.\345\210\206\350\213\271\346\236\234.py" @@ -1,16 +1,16 @@ -# 可分条件:平均为整数,比平均多的部分可被2整除,且整除结果就是移动次数 -n = int(raw_input()) -s = [int(i) for i in raw_input().split()] -if sum(s)%len(s)!=0: - print(-1) -else: - count = 0 - avg = sum(s)/len(s) - for i in s: - if i > avg: - if (i-avg)%2==0: - count += (i-avg)/2 - else: - count = -1 - break +# 可分条件:平均为整数,比平均多的部分可被2整除,且整除结果就是移动次数 +n = int(raw_input()) +s = [int(i) for i in raw_input().split()] +if sum(s)%len(s)!=0: + print(-1) +else: + count = 0 + avg = sum(s)/len(s) + for i in s: + if i > avg: + if (i-avg)%2==0: + count += (i-avg)/2 + else: + count = -1 + break print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/06.\346\230\237\351\231\205\347\251\277\350\266\212.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/06.\346\230\237\351\231\205\347\251\277\350\266\212.py" similarity index 94% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/06.\346\230\237\351\231\205\347\251\277\350\266\212.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/06.\346\230\237\351\231\205\347\251\277\350\266\212.py" index a20f23a..4f8b8c1 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/06.\346\230\237\351\231\205\347\251\277\350\266\212.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/06.\346\230\237\351\231\205\347\251\277\350\266\212.py" @@ -1,12 +1,12 @@ -# 解方程 x*x+x<=h -# 方法一 -import math -h = int(raw_input()) -x = int(math.sqrt(h)) -if h-x*x>=x: - print(x) -else: - print(x-1) - -# 方法二 +# 解方程 x*x+x<=h +# 方法一 +import math +h = int(raw_input()) +x = int(math.sqrt(h)) +if h-x*x>=x: + print(x) +else: + print(x-1) + +# 方法二 print(int(((1+4*input())**0.5-1)/2)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/07.\350\227\217\345\256\235\345\233\276.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/07.\350\227\217\345\256\235\345\233\276.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/07.\350\227\217\345\256\235\345\233\276.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/07.\350\227\217\345\256\235\345\233\276.py" index 2918ef5..50f3aeb 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/07.\350\227\217\345\256\235\345\233\276.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/07.\350\227\217\345\256\235\345\233\276.py" @@ -1,17 +1,17 @@ -# 方法一:索引递增 -s, t = raw_input(), raw_input() -j = flag = 0 -for i in s: - if i == t[j]: - j += 1 - if j == len(t): - flag = 1 - break -print('Yes' if flag else 'No') - -# 方法二:字符串截取 -s, t = raw_input(), raw_input() -for i in s: - if t and i == t[0]: - t = t[1:] +# 方法一:索引递增 +s, t = raw_input(), raw_input() +j = flag = 0 +for i in s: + if i == t[j]: + j += 1 + if j == len(t): + flag = 1 + break +print('Yes' if flag else 'No') + +# 方法二:字符串截取 +s, t = raw_input(), raw_input() +for i in s: + if t and i == t[0]: + t = t[1:] print('No' if t else 'Yes') \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/08.\346\225\260\345\210\227\350\277\230\345\216\237.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/08.\346\225\260\345\210\227\350\277\230\345\216\237.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/08.\346\225\260\345\210\227\350\277\230\345\216\237.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/08.\346\225\260\345\210\227\350\277\230\345\216\237.py" index adb624a..e457ead 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/08.\346\225\260\345\210\227\350\277\230\345\216\237.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/08.\346\225\260\345\210\227\350\277\230\345\216\237.py" @@ -1,32 +1,32 @@ -import itertools -n, k = map(int, raw_input().split()) -A = map(int, raw_input().split()) -miss_num = [] -miss_index = [] -res = 0 -# 计算序列顺序对个数 -def findCount(): - count = 0 - for i in range(len(A)-1): - j = i+1 - while j 111010 --> 111010 --> 111010 --> 111010 --> 111010 -# 111010 --> 110110 --> 001100 --> 010111 --> 010111 --> 010111 -# 101101 --> 101101 --> 010111 --> 010000 --> 000111 --> 001100 -# 110110 --> 101010 --> 010000 --> 001100 --> 001100 --> 000111 - -n = int(raw_input()) -X = map(int, raw_input().split()) -for i in range(n-1,0,-1): - X.sort() - for j in range(i-1,-1,-1): - if X[i]^X[j] < X[j]: - X[j] ^= X[i] -for i in range(n): - if X[i]!=0: - print (n-i) +# 进行行与行之间的xor,其中1^1=0; 0^0=0; 1^0=1; 0^1=1; + +# 矩阵的秩定义:是其行向量或列向量的极大无关组中包含向量的个数。 +# 矩阵的秩求法:用初等行变换化成梯矩阵, 梯矩阵中非零行数就是矩阵的秩 + +# 问题理解:输入n个数,将这些数之间进行多次xor(异或操作),其中一个数可能被xor多次,看最后能剩余多少不重复的数,输出数量即可。 +# 思路:类似矩阵求秩,首先将各数从大到小排序,对位数与该行相同的进行异或操作 + +# 具体过程如下: +# 排序 i=0 异或 排序 i=1 异或 排序 i=2 +# 101010 --> 111010 --> 111010 --> 111010 --> 111010 --> 111010 +# 111010 --> 110110 --> 001100 --> 010111 --> 010111 --> 010111 +# 101101 --> 101101 --> 010111 --> 010000 --> 000111 --> 001100 +# 110110 --> 101010 --> 010000 --> 001100 --> 001100 --> 000111 + +n = int(raw_input()) +X = map(int, raw_input().split()) +for i in range(n-1,0,-1): + X.sort() + for j in range(i-1,-1,-1): + if X[i]^X[j] < X[j]: + X[j] ^= X[i] +for i in range(n): + if X[i]!=0: + print (n-i) break \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/10.\345\271\270\350\277\220\347\232\204\350\242\213\345\255\220.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/10.\345\271\270\350\277\220\347\232\204\350\242\213\345\255\220.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/10.\345\271\270\350\277\220\347\232\204\350\242\213\345\255\220.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/10.\345\271\270\350\277\220\347\232\204\350\242\213\345\255\220.py" index 91c5091..467cf75 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/10.\345\271\270\350\277\220\347\232\204\350\242\213\345\255\220.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/10.\345\271\270\350\277\220\347\232\204\350\242\213\345\255\220.py" @@ -1,23 +1,23 @@ -# 递归 -n = int(raw_input()) -x = map(int, raw_input().split()) -x.sort() -def lucky(x, lsum, lmul): - res = 0 - for i in range(len(x)): - if i>0 and x[i]==x[i-1]: - continue - lsum += x[i] - lmul *= x[i] - if lsum > lmul: - # 符合条件则继续往下扩展一位 - res = res+1+lucky(x[i+1:], lsum, lmul) - elif x[i] == 1: - res = res+lucky(x[i+1:], lsum, lmul) - else: - break - # 回溯一位,继续扩展 - lsum -= x[i] - lmul /= x[i] - return res +# 递归 +n = int(raw_input()) +x = map(int, raw_input().split()) +x.sort() +def lucky(x, lsum, lmul): + res = 0 + for i in range(len(x)): + if i>0 and x[i]==x[i-1]: + continue + lsum += x[i] + lmul *= x[i] + if lsum > lmul: + # 符合条件则继续往下扩展一位 + res = res+1+lucky(x[i+1:], lsum, lmul) + elif x[i] == 1: + res = res+lucky(x[i+1:], lsum, lmul) + else: + break + # 回溯一位,继续扩展 + lsum -= x[i] + lmul /= x[i] + return res print(lucky(x, 0, 1)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/11.\344\270\215\350\246\201\344\272\214.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/11.\344\270\215\350\246\201\344\272\214.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/11.\344\270\215\350\246\201\344\272\214.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/11.\344\270\215\350\246\201\344\272\214.py" index 96c52f5..32ca2d6 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/11.\344\270\215\350\246\201\344\272\214.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/11.\344\270\215\350\246\201\344\272\214.py" @@ -1,14 +1,14 @@ -# ** ** ** -# ** ** ** -# ** ** ** -# ** ** ** -# ** ** ** -# ** ** ** -# 由数据规律分三种情况讨论 -n, m = map(int, raw_input().split()) -if n%4==0 or m%4==0: - print(n*m/2) -elif n%2==0 and m%2==0: - print((n*m/4+1)*2) -else: +# ** ** ** +# ** ** ** +# ** ** ** +# ** ** ** +# ** ** ** +# ** ** ** +# 由数据规律分三种情况讨论 +n, m = map(int, raw_input().split()) +if n%4==0 or m%4==0: + print(n*m/2) +elif n%2==0 and m%2==0: + print((n*m/4+1)*2) +else: print(n*m/2+1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/12.\350\247\243\346\225\221\345\260\217\346\230\223.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/12.\350\247\243\346\225\221\345\260\217\346\230\223.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/12.\350\247\243\346\225\221\345\260\217\346\230\223.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/12.\350\247\243\346\225\221\345\260\217\346\230\223.py" index 28a00c6..228c181 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/12.\350\247\243\346\225\221\345\260\217\346\230\223.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/12.\350\247\243\346\225\221\345\260\217\346\230\223.py" @@ -1,8 +1,8 @@ -# 起点到陷阱的最短距离为x+y-2 -num = int(raw_input()) -x = [int(i) for i in raw_input().split()] -y = [int(i) for i in raw_input().split()] -a = [] -for j in range(num): - a.append(x[j]+y[j]-2) +# 起点到陷阱的最短距离为x+y-2 +num = int(raw_input()) +x = [int(i) for i in raw_input().split()] +y = [int(i) for i in raw_input().split()] +a = [] +for j in range(num): + a.append(x[j]+y[j]-2) print(min(a)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/13.\347\273\237\350\256\241\345\233\236\346\226\207.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/13.\347\273\237\350\256\241\345\233\236\346\226\207.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/13.\347\273\237\350\256\241\345\233\236\346\226\207.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/13.\347\273\237\350\256\241\345\233\236\346\226\207.py" index 36e1ecb..1fd2094 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/13.\347\273\237\350\256\241\345\233\236\346\226\207.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/13.\347\273\237\350\256\241\345\233\236\346\226\207.py" @@ -1,12 +1,12 @@ -# 插入后反转字符串,若与原来相等则是回文串 -a = list(raw_input()) -b = raw_input() -c = a[:] -count = 0 -for i in range(len(c)+1): - a.insert(i, b) - s = ''.join(a) - if s[:]==s[::-1]: - count += 1 - a = c[:] +# 插入后反转字符串,若与原来相等则是回文串 +a = list(raw_input()) +b = raw_input() +c = a[:] +count = 0 +for i in range(len(c)+1): + a.insert(i, b) + s = ''.join(a) + if s[:]==s[::-1]: + count += 1 + a = c[:] print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/14.\351\245\245\351\245\277\347\232\204\345\260\217\346\230\223.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/14.\351\245\245\351\245\277\347\232\204\345\260\217\346\230\223.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/14.\351\245\245\351\245\277\347\232\204\345\260\217\346\230\223.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/14.\351\245\245\351\245\277\347\232\204\345\260\217\346\230\223.py" index d385b71..f21a6b3 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/14.\351\245\245\351\245\277\347\232\204\345\260\217\346\230\223.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/14.\351\245\245\351\245\277\347\232\204\345\260\217\346\230\223.py" @@ -1,31 +1,31 @@ -# 设f(x)=4x+3,g(x)=8x+7。计算可以得到以下两个规律: -# (1) g(f(x))=f(g(x)) 即f和g的执行顺序没有影响。 -# (2) f(f(f(x)))=g(g(x)) 即做3次f变换等价于做2次g变换 -# 由于规律(1),可以调整其变换的顺序。如ffggfggff可以转化成 fffffgggg -# 由于规律(2),为了使执行次数最少,每3个f可以转化成2个g。如fffffgggg可以转化成ffgggggg。 -# 因此一个最优的策略,f的执行次数只能为0,1,2。对于输入的x,只需要求x,4x+3,4(4x+3)+3的最小g执行次数就可以了。 -x = int(raw_input()) -num = 100001 -base = [x, 4*x+3, 4*(4*x+3)+3] -for i,v in enumerate(base): - for j in range(100000): - v = (8*v+7)%1000000007 - if v == 0: - num = min(num, i+j+1) - break -if num == 100001: - print(-1) -else: - print(num) - - -# 4x+3相当于做了两次2x+1, 8x+7做了三次。 -# 从起点开始令x0 = 2*x0+1,统计做了多少次2x+1后模1000000007等于0 -# 再把次数分解成若干个3与2的和,3的个数加上2的个数最小,不超过100000 -x = int(raw_input()) -r = 0 -while x!=0 and r<=300000: - x = (2*x+1)%1000000007 - r += 1 -s = (r+2)/3 +# 设f(x)=4x+3,g(x)=8x+7。计算可以得到以下两个规律: +# (1) g(f(x))=f(g(x)) 即f和g的执行顺序没有影响。 +# (2) f(f(f(x)))=g(g(x)) 即做3次f变换等价于做2次g变换 +# 由于规律(1),可以调整其变换的顺序。如ffggfggff可以转化成 fffffgggg +# 由于规律(2),为了使执行次数最少,每3个f可以转化成2个g。如fffffgggg可以转化成ffgggggg。 +# 因此一个最优的策略,f的执行次数只能为0,1,2。对于输入的x,只需要求x,4x+3,4(4x+3)+3的最小g执行次数就可以了。 +x = int(raw_input()) +num = 100001 +base = [x, 4*x+3, 4*(4*x+3)+3] +for i,v in enumerate(base): + for j in range(100000): + v = (8*v+7)%1000000007 + if v == 0: + num = min(num, i+j+1) + break +if num == 100001: + print(-1) +else: + print(num) + + +# 4x+3相当于做了两次2x+1, 8x+7做了三次。 +# 从起点开始令x0 = 2*x0+1,统计做了多少次2x+1后模1000000007等于0 +# 再把次数分解成若干个3与2的和,3的个数加上2的个数最小,不超过100000 +x = int(raw_input()) +r = 0 +while x!=0 and r<=300000: + x = (2*x+1)%1000000007 + r += 1 +s = (r+2)/3 print -1 if s>10**5 else s \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/15.\344\270\244\347\247\215\346\216\222\345\272\217\346\226\271\346\263\225.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/15.\344\270\244\347\247\215\346\216\222\345\272\217\346\226\271\346\263\225.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/15.\344\270\244\347\247\215\346\216\222\345\272\217\346\226\271\346\263\225.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/15.\344\270\244\347\247\215\346\216\222\345\272\217\346\226\271\346\263\225.py" index 1b09301..da974c3 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/15.\344\270\244\347\247\215\346\216\222\345\272\217\346\226\271\346\263\225.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/15.\344\270\244\347\247\215\346\216\222\345\272\217\346\226\271\346\263\225.py" @@ -1,19 +1,19 @@ -# 字符串序列或字符串对应的长度序列调用sort()方法后,若与原序列相同,则已经排好序了 -n = int(raw_input()) -str1 = [] -len1 = [] -for i in range(n): - str1.append(raw_input()) - len1.append(len(str1[i])) -str2, len2 = str1[:], len1[:] -str2.sort() -len2.sort() -if len1 == len2: - if str1 == str2: - print('both') - else: - print('lengths') -elif str1 == str2: - print('lexicographically') -else: +# 字符串序列或字符串对应的长度序列调用sort()方法后,若与原序列相同,则已经排好序了 +n = int(raw_input()) +str1 = [] +len1 = [] +for i in range(n): + str1.append(raw_input()) + len1.append(len(str1[i])) +str2, len2 = str1[:], len1[:] +str2.sort() +len2.sort() +if len1 == len2: + if str1 == str2: + print('both') + else: + print('lengths') +elif str1 == str2: + print('lexicographically') +else: print('none') \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/16.\345\260\217\346\230\223\345\226\234\346\254\242\347\232\204\345\215\225\350\257\215.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/16.\345\260\217\346\230\223\345\226\234\346\254\242\347\232\204\345\215\225\350\257\215.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/16.\345\260\217\346\230\223\345\226\234\346\254\242\347\232\204\345\215\225\350\257\215.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/16.\345\260\217\346\230\223\345\226\234\346\254\242\347\232\204\345\215\225\350\257\215.py" index e3599f1..7587695 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/16.\345\260\217\346\230\223\345\226\234\346\254\242\347\232\204\345\215\225\350\257\215.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/16.\345\260\217\346\230\223\345\226\234\346\254\242\347\232\204\345\215\225\350\257\215.py" @@ -1,12 +1,12 @@ -# 各条件逐一判断 -s = raw_input() -res = 'Likes' -if not s.isupper(): - res = 'Dislikes' -for i in range(len(s)-1): - if s[i] == s[i+1]: - res = 'Dislikes' -for i in range(len(s)-3): - if s[i] == s[i+2] and s[i+1] == s[i+3]: - res = 'Dislikes' +# 各条件逐一判断 +s = raw_input() +res = 'Likes' +if not s.isupper(): + res = 'Dislikes' +for i in range(len(s)-1): + if s[i] == s[i+1]: + res = 'Dislikes' +for i in range(len(s)-3): + if s[i] == s[i+2] and s[i+1] == s[i+3]: + res = 'Dislikes' print(res) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/17.Fibonacci\346\225\260\345\210\227.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/17.Fibonacci\346\225\260\345\210\227.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/17.Fibonacci\346\225\260\345\210\227.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/17.Fibonacci\346\225\260\345\210\227.py" index 0cdf395..f427221 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/17.Fibonacci\346\225\260\345\210\227.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/17.Fibonacci\346\225\260\345\210\227.py" @@ -1,6 +1,6 @@ -# 递推找到离整数最近的左右两个Fibonacci数,求差取最小即为最少步数 -a, b = 0, 1 -n = int(raw_input()) -while n>b: - a, b = b, a+b +# 递推找到离整数最近的左右两个Fibonacci数,求差取最小即为最少步数 +a, b = 0, 1 +n = int(raw_input()) +while n>b: + a, b = b, a+b print(min(n-a, b-n)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/18.\346\225\260\345\255\227\346\270\270\346\210\217.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/18.\346\225\260\345\255\227\346\270\270\346\210\217.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/18.\346\225\260\345\255\227\346\270\270\346\210\217.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/18.\346\225\260\345\255\227\346\270\270\346\210\217.py" index 3644404..480b54a 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/18.\346\225\260\345\255\227\346\270\270\346\210\217.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/18.\346\225\260\345\255\227\346\270\270\346\210\217.py" @@ -1,11 +1,11 @@ -# 1,2,3,7求和结果为13,则可组成的数为1-13 -n = int(raw_input()) -a = map(int, raw_input().split()) -a.sort() -res = 0 -for i in a: - # 相减大于1说明有空档 - if i-res>1: - break - res += i +# 1,2,3,7求和结果为13,则可组成的数为1-13 +n = int(raw_input()) +a = map(int, raw_input().split()) +a.sort() +res = 0 +for i in a: + # 相减大于1说明有空档 + if i-res>1: + break + res += i print(res+1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/19.\346\264\227\347\211\214.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/19.\346\264\227\347\211\214.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/19.\346\264\227\347\211\214.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/19.\346\264\227\347\211\214.py" index dc0dfc6..796428c 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/19.\346\264\227\347\211\214.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/19.\346\264\227\347\211\214.py" @@ -1,14 +1,14 @@ -# 一轮洗牌:1,2,3,4,5,6 --> 1,4,2,5,3,6 -t = int(raw_input()) -n, k = map(int, raw_input().split()) -for _ in range(t): - data = raw_input().split() - num = data[:2*n] - res = ['']*(2*n) - for _ in range(k): - # 插空排放 - res[::2] = num[:n] - res[1::2] = num[n:] - num = res[:] - n, k = int(data[-2]), int(data[-1]) +# 一轮洗牌:1,2,3,4,5,6 --> 1,4,2,5,3,6 +t = int(raw_input()) +n, k = map(int, raw_input().split()) +for _ in range(t): + data = raw_input().split() + num = data[:2*n] + res = ['']*(2*n) + for _ in range(k): + # 插空排放 + res[::2] = num[:n] + res[1::2] = num[n:] + num = res[:] + n, k = int(data[-2]), int(data[-1]) print(' '.join(res)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/20.\346\236\204\351\200\240\351\230\237\345\210\227.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/20.\346\236\204\351\200\240\351\230\237\345\210\227.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/20.\346\236\204\351\200\240\351\230\237\345\210\227.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/20.\346\236\204\351\200\240\351\230\237\345\210\227.py" index 40f9058..3737e21 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/20.\346\236\204\351\200\240\351\230\237\345\210\227.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/20.\346\236\204\351\200\240\351\230\237\345\210\227.py" @@ -1,11 +1,11 @@ -# 逆推 -# 原操作:1、将队首元素放到队尾 2、将新队首元素输出 -# 逆操作:1、将输出元素插入到队首 2、将队尾元素插入到队首 -t = int(raw_input()) -for _ in range(t): - n = int(raw_input()) - res = [] - for i in range(n, 0, -1): - res.insert(0, i) - res.insert(0, res.pop()) +# 逆推 +# 原操作:1、将队首元素放到队尾 2、将新队首元素输出 +# 逆操作:1、将输出元素插入到队首 2、将队尾元素插入到队首 +t = int(raw_input()) +for _ in range(t): + n = int(raw_input()) + res = [] + for i in range(n, 0, -1): + res.insert(0, i) + res.insert(0, res.pop()) print(' '.join(map(str, res))) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/21.\345\233\236\346\226\207\345\272\217\345\210\227.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/21.\345\233\236\346\226\207\345\272\217\345\210\227.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/21.\345\233\236\346\226\207\345\272\217\345\210\227.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/21.\345\233\236\346\226\207\345\272\217\345\210\227.py" index e5e3af7..6bb2752 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/21.\345\233\236\346\226\207\345\272\217\345\210\227.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/21.\345\233\236\346\226\207\345\272\217\345\210\227.py" @@ -1,18 +1,18 @@ -# 比较首尾两个数,两个数不相等就进行加法,较小的数加上与其相邻的值 -def getNum(item, left, right, head, tail, time): - if head >= tail: - return time - elif left < right: - head, time = head+1, time+1 - left += item[head] - elif left > right: - tail, time = tail-1, time+1 - right += item[tail] - else: - head, tail = head+1, tail-1 - left, right = item[head], item[tail] - return getNum(item, left, right, head, tail, time) - -n = int(raw_input()) -item = map(int, raw_input().split()) +# 比较首尾两个数,两个数不相等就进行加法,较小的数加上与其相邻的值 +def getNum(item, left, right, head, tail, time): + if head >= tail: + return time + elif left < right: + head, time = head+1, time+1 + left += item[head] + elif left > right: + tail, time = tail-1, time+1 + right += item[tail] + else: + head, tail = head+1, tail-1 + left, right = item[head], item[tail] + return getNum(item, left, right, head, tail, time) + +n = int(raw_input()) +item = map(int, raw_input().split()) print(getNum(item, item[0], item[-1], 0 ,n-1, 0)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/22.\344\274\230\351\233\205\347\232\204\347\202\271.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/22.\344\274\230\351\233\205\347\232\204\347\202\271.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/22.\344\274\230\351\233\205\347\232\204\347\202\271.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/22.\344\274\230\351\233\205\347\232\204\347\202\271.py" index 875e691..49c69a7 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/22.\344\274\230\351\233\205\347\232\204\347\202\271.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/22.\344\274\230\351\233\205\347\232\204\347\202\271.py" @@ -1,14 +1,14 @@ -import math -n = int(raw_input()) -i = count = 0 -while i**2 <= n/2.0: - j_square = n-i**2 - j = int(math.sqrt(j_square)) - # 验证该数是否为整数 - if j**2==j_square: - if i==0 or i==j: - count += 4 - else: - count += 8 - i += 1 +import math +n = int(raw_input()) +i = count = 0 +while i**2 <= n/2.0: + j_square = n-i**2 + j = int(math.sqrt(j_square)) + # 验证该数是否为整数 + if j**2==j_square: + if i==0 or i==j: + count += 4 + else: + count += 8 + i += 1 print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/23.\350\267\263\347\237\263\346\235\277.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/23.\350\267\263\347\237\263\346\235\277.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/23.\350\267\263\347\237\263\346\235\277.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/23.\350\267\263\347\237\263\346\235\277.py" index 121932b..21cf0dd 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/23.\350\267\263\347\237\263\346\235\277.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/23.\350\267\263\347\237\263\346\235\277.py" @@ -1,16 +1,16 @@ -N,M=map(int,raw_input().split()) -divs = [[] for i in range(M+1)] -#i 表示公约数 公因子 以2开始算 -for i in range(2, M+1): - for j in range(i+i, M+1, i): - #j表示以i为约数的所有数,即都有公共约数i 通过这两个嵌套循环,实现了每个位置j上都有对应的一组约数 - divs[j].append(i) -res = [0]*(M+1) -#表示步数,初始化为1,到最后面减1 -res[N] = 1 -for n in range(N, M): - if res[n]: - for dn in divs[n]: - if n + dn <= M: - res[n+dn] = min(res[n+dn], res[n] + 1) if res[n+dn] else res[n] + 1 +N,M=map(int,raw_input().split()) +divs = [[] for i in range(M+1)] +#i 表示公约数 公因子 以2开始算 +for i in range(2, M+1): + for j in range(i+i, M+1, i): + #j表示以i为约数的所有数,即都有公共约数i 通过这两个嵌套循环,实现了每个位置j上都有对应的一组约数 + divs[j].append(i) +res = [0]*(M+1) +#表示步数,初始化为1,到最后面减1 +res[N] = 1 +for n in range(N, M): + if res[n]: + for dn in divs[n]: + if n + dn <= M: + res[n+dn] = min(res[n+dn], res[n] + 1) if res[n+dn] else res[n] + 1 print(res[M]-1 if res[M] else -1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/24.\346\232\227\351\273\221\347\232\204\345\255\227\347\254\246\344\270\262.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/24.\346\232\227\351\273\221\347\232\204\345\255\227\347\254\246\344\270\262.py" similarity index 94% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/24.\346\232\227\351\273\221\347\232\204\345\255\227\347\254\246\344\270\262.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/24.\346\232\227\351\273\221\347\232\204\345\255\227\347\254\246\344\270\262.py" index 94c6b51..6cde8ce 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/24.\346\232\227\351\273\221\347\232\204\345\255\227\347\254\246\344\270\262.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/24.\346\232\227\351\273\221\347\232\204\345\255\227\347\254\246\344\270\262.py" @@ -1,31 +1,31 @@ -# f(1)=3 f(2)=9 f(3)=21 -# f(n)= 2*f(n-1)+f(n-2) - -# 递归写法 -def cal(n): - if n==1: - return 3 - if n==2: - return 9 - return 2*cal(n-1) + cal(n-2) -n = int(raw_input()) -print(cal(n)) - -# 递推写法 -n = int(raw_input()) -a, b = 3, 9 -if n==1: - print(a) -elif n==2: - print(b) -else: - for _ in range(n-2): - a, b = b, 2*b+a - print(b) - -# 数组追加写法 -n = int(raw_input()) -res = [3,9] -for i in range(2, n): - res.append(2*res[i-1] + res[i-2]) +# f(1)=3 f(2)=9 f(3)=21 +# f(n)= 2*f(n-1)+f(n-2) + +# 递归写法 +def cal(n): + if n==1: + return 3 + if n==2: + return 9 + return 2*cal(n-1) + cal(n-2) +n = int(raw_input()) +print(cal(n)) + +# 递推写法 +n = int(raw_input()) +a, b = 3, 9 +if n==1: + print(a) +elif n==2: + print(b) +else: + for _ in range(n-2): + a, b = b, 2*b+a + print(b) + +# 数组追加写法 +n = int(raw_input()) +res = [3,9] +for i in range(2, n): + res.append(2*res[i-1] + res[i-2]) print(res[n-1]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/25.\346\225\260\345\255\227\347\277\273\350\275\254.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/25.\346\225\260\345\255\227\347\277\273\350\275\254.py" similarity index 98% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/25.\346\225\260\345\255\227\347\277\273\350\275\254.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/25.\346\225\260\345\255\227\347\277\273\350\275\254.py" index ec390e5..a17906b 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/25.\346\225\260\345\255\227\347\277\273\350\275\254.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/25.\346\225\260\345\255\227\347\277\273\350\275\254.py" @@ -1,4 +1,4 @@ -# rev(rev(x) + rev(y)) 利用字符串的反转功能实现即可 -x, y = raw_input().split() -x, y = int(x[::-1]), int(y[::-1]) +# rev(rev(x) + rev(y)) 利用字符串的反转功能实现即可 +x, y = raw_input().split() +x, y = int(x[::-1]), int(y[::-1]) print(int(str(x+y)[::-1])) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/26.\346\234\200\345\244\247\347\232\204\345\245\207\347\272\246\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/26.\346\234\200\345\244\247\347\232\204\345\245\207\347\272\246\346\225\260.py" similarity index 98% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/26.\346\234\200\345\244\247\347\232\204\345\245\207\347\272\246\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/26.\346\234\200\345\244\247\347\232\204\345\245\207\347\272\246\346\225\260.py" index 42068a3..f37280e 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/26.\346\234\200\345\244\247\347\232\204\345\245\207\347\272\246\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/26.\346\234\200\345\244\247\347\232\204\345\245\207\347\272\246\346\225\260.py" @@ -1,16 +1,16 @@ -# 总体思路:奇数的最大奇数约数就是自己。对于偶数只能一直除2,直到得到一个奇数即为最大奇数约数 -# 比如n=10,即1 2 3 4 5 6 7 8 9 10 。此时奇数有1 3 5 7 9 ,将这几个奇数相加 -# 然后n/2,得到第二轮序列序列 1 2 3 4 5 分别对应上次的2 4 6 8 10 五个偶数,其中1 3 5是2 6 10的最大奇约数。依次类推 - -# 当n为偶数,就有n/2个奇数,根据等差数列求和公式 即((首项+末项)*项数)/2,则n/2个奇数和为((1+n-1)*n/2)/2, -# 即为(n/2) * (n/2),此时n为偶数,因此 (n/2) * (n/2) = ((n+1)/2) * ((n+1)/2) - -# 当n为奇数,有(n+1)/2个奇数,此时奇数和为((n+1)/2) * ((n+1)/2) -# 因此两种情况可以用一个等式来总结 - -n = int(raw_input()) -res = 0 -while n: - res += ((n+1)/2)**2 - n /= 2 +# 总体思路:奇数的最大奇数约数就是自己。对于偶数只能一直除2,直到得到一个奇数即为最大奇数约数 +# 比如n=10,即1 2 3 4 5 6 7 8 9 10 。此时奇数有1 3 5 7 9 ,将这几个奇数相加 +# 然后n/2,得到第二轮序列序列 1 2 3 4 5 分别对应上次的2 4 6 8 10 五个偶数,其中1 3 5是2 6 10的最大奇约数。依次类推 + +# 当n为偶数,就有n/2个奇数,根据等差数列求和公式 即((首项+末项)*项数)/2,则n/2个奇数和为((1+n-1)*n/2)/2, +# 即为(n/2) * (n/2),此时n为偶数,因此 (n/2) * (n/2) = ((n+1)/2) * ((n+1)/2) + +# 当n为奇数,有(n+1)/2个奇数,此时奇数和为((n+1)/2) * ((n+1)/2) +# 因此两种情况可以用一个等式来总结 + +n = int(raw_input()) +res = 0 +while n: + res += ((n+1)/2)**2 + n /= 2 print(res) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/27.\344\271\260\350\213\271\346\236\234.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/27.\344\271\260\350\213\271\346\236\234.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/27.\344\271\260\350\213\271\346\236\234.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/27.\344\271\260\350\213\271\346\236\234.py" index 96a5af3..daa6827 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/27.\344\271\260\350\213\271\346\236\234.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/27.\344\271\260\350\213\271\346\236\234.py" @@ -1,25 +1,25 @@ -# 动态规划 -n = int(raw_input()) -count = 100 -# 买8的袋数 -for i in range(n/8+1): - num = n-i*8 - # 余下买6 - if num%6==0: - count = min(count, i+num/6) -print -1 if count==100 else count - - -# 数字分析 -# 偶数个苹果数对8取模,其结果只可能为0,2,4,6 -# 若余数为0,恰好用于买每袋8个 -# 若余数为6,不需回溯,直接再购买一袋6个 n/8+1 -# 若余数为4,只需回溯1次即可,因为8+4=12, 12%6=0 (n/8-1)+2 = n/8+1 -# 若余数为2,只需回溯2次即可,因为8+8+2=18, 18%6=0 (n/8-2)+3 = n/8+1 -n = int(raw_input()) -if n%8==0: - print(n/8) -elif n%8 in [2,4,6]: - print(n/8+1) -else: +# 动态规划 +n = int(raw_input()) +count = 100 +# 买8的袋数 +for i in range(n/8+1): + num = n-i*8 + # 余下买6 + if num%6==0: + count = min(count, i+num/6) +print -1 if count==100 else count + + +# 数字分析 +# 偶数个苹果数对8取模,其结果只可能为0,2,4,6 +# 若余数为0,恰好用于买每袋8个 +# 若余数为6,不需回溯,直接再购买一袋6个 n/8+1 +# 若余数为4,只需回溯1次即可,因为8+4=12, 12%6=0 (n/8-1)+2 = n/8+1 +# 若余数为2,只需回溯2次即可,因为8+8+2=18, 18%6=0 (n/8-2)+3 = n/8+1 +n = int(raw_input()) +if n%8==0: + print(n/8) +elif n%8 in [2,4,6]: + print(n/8+1) +else: print(-1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/28.\350\256\241\347\256\227\347\263\226\346\236\234.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/28.\350\256\241\347\256\227\347\263\226\346\236\234.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/28.\350\256\241\347\256\227\347\263\226\346\236\234.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/28.\350\256\241\347\256\227\347\263\226\346\236\234.py" index 9b34542..3fe70da 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/28.\350\256\241\347\256\227\347\263\226\346\236\234.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/28.\350\256\241\347\256\227\347\263\226\346\236\234.py" @@ -1,9 +1,9 @@ -# 先按表达式求出ABC的值,再做逆运算验证是否正确 -n = [int(i) for i in raw_input().split()] -A = (n[0]+n[2])/2 -B = (n[1]+n[3])/2 -C = B - n[1] -if A-B==n[0]: - print(A,B,C) -else: +# 先按表达式求出ABC的值,再做逆运算验证是否正确 +n = [int(i) for i in raw_input().split()] +A = (n[0]+n[2])/2 +B = (n[1]+n[3])/2 +C = B - n[1] +if A-B==n[0]: + print(A,B,C) +else: print('No') \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/29.\350\277\236\347\273\255\346\234\200\345\244\247\345\222\214.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/29.\350\277\236\347\273\255\346\234\200\345\244\247\345\222\214.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/29.\350\277\236\347\273\255\346\234\200\345\244\247\345\222\214.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/29.\350\277\236\347\273\255\346\234\200\345\244\247\345\222\214.py" index b05d576..8334f42 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/29.\350\277\236\347\273\255\346\234\200\345\244\247\345\222\214.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/29.\350\277\236\347\273\255\346\234\200\345\244\247\345\222\214.py" @@ -1,15 +1,15 @@ -n = int(raw_input()) -nums = list(map(int, raw_input().split())) -max_sum = cur_sum = 0 -if max(nums)<0: - nums.sort() - print(nums[-1]) -else: - for i in nums: - cur_sum += i - if cur_sum > max_sum: - max_sum = cur_sum - # 小于0说明前面求和负大于正,重新设置起点 - if cur_sum < 0: - cur_sum = 0 +n = int(raw_input()) +nums = list(map(int, raw_input().split())) +max_sum = cur_sum = 0 +if max(nums)<0: + nums.sort() + print(nums[-1]) +else: + for i in nums: + cur_sum += i + if cur_sum > max_sum: + max_sum = cur_sum + # 小于0说明前面求和负大于正,重新设置起点 + if cur_sum < 0: + cur_sum = 0 print(max_sum) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/30.\351\244\220\351\246\206.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/30.\351\244\220\351\246\206.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/30.\351\244\220\351\246\206.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/30.\351\244\220\351\246\206.py" index dbdf6fb..eacc891 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/30.\351\244\220\351\246\206.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/30.\351\244\220\351\246\206.py" @@ -1,17 +1,17 @@ -import bisect -n, m = map(int, raw_input().split()) -a = map(int, raw_input().split()) -p = [map(int, raw_input().split()) for _ in range(m)] -a.sort() -# 按消费高到低排序 -p.sort(key=lambda x: x[1], reverse=True) -count = 0 -# 遍历客人 -for i in range(len(p)): - # 二分法查找,返回该数值将会插入的位置但不会插入,即得到≥该数的索引 - j = bisect.bisect_left(a, p[i][0]) - if j>=len(a): - continue - count += p[i][1] - del a[j] +import bisect +n, m = map(int, raw_input().split()) +a = map(int, raw_input().split()) +p = [map(int, raw_input().split()) for _ in range(m)] +a.sort() +# 按消费高到低排序 +p.sort(key=lambda x: x[1], reverse=True) +count = 0 +# 遍历客人 +for i in range(len(p)): + # 二分法查找,返回该数值将会插入的位置但不会插入,即得到≥该数的索引 + j = bisect.bisect_left(a, p[i][0]) + if j>=len(a): + continue + count += p[i][1] + del a[j] print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/31.\345\234\260\344\270\213\350\277\267\345\256\253.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/31.\345\234\260\344\270\213\350\277\267\345\256\253.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/31.\345\234\260\344\270\213\350\277\267\345\256\253.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/31.\345\234\260\344\270\213\350\277\267\345\256\253.py" index c459850..d69413e 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/31.\345\234\260\344\270\213\350\277\267\345\256\253.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/31.\345\234\260\344\270\213\350\277\267\345\256\253.py" @@ -1,33 +1,33 @@ -# coding=utf-8 -def isValid(matrix,n,m,p,x,y,visited): - isvisit = (x*m+y in visited) # 是否已访问 - isvalid = (0<=x=0) # 是否有剩余能量值 - return not isvisit and isvalid and hasp # 是否可走 - -def getPath(matrix, n, m, p, x, y, visited, path): - if (x,y) == (0,m-1): - return True - # 向右,向上,向左,向下 (贪心思想,尽可能以最小的消耗靠近右上角的终点) - nextpos=[(x,y+1,p-1),(x-1,y,p-3),(x,y-1,p-1),(x+1,y,p)] - for nextx,nexty,nextp in nextpos: - if isValid(matrix, n, m, nextp, nextx, nexty, visited): - path.append([nextx,nexty]) - visited.add(nextx*m + nexty) - # 由该点延伸出来的路径是否能到达终点,如果成功,则该路径是体力消耗最小的路径 - if getPath(matrix, n, m, nextp, nextx, nexty, visited, path): - return True - # 如果不成功,移除该路径,继续判断下一路径 - path.pop(-1) - visited.remove(nextx*m + nexty) - return False - -if __name__ == '__main__': - n, m, p = map(int, raw_input().split()) - matrix = [map(int, raw_input().split()) for _ in range(n)] - visited = set() - path = [[0,0]] - if getPath(matrix, n, m, p, 0, 0, visited, path): - print(','.join(map(str, path)).replace(' ', '')) - else: +# coding=utf-8 +def isValid(matrix,n,m,p,x,y,visited): + isvisit = (x*m+y in visited) # 是否已访问 + isvalid = (0<=x=0) # 是否有剩余能量值 + return not isvisit and isvalid and hasp # 是否可走 + +def getPath(matrix, n, m, p, x, y, visited, path): + if (x,y) == (0,m-1): + return True + # 向右,向上,向左,向下 (贪心思想,尽可能以最小的消耗靠近右上角的终点) + nextpos=[(x,y+1,p-1),(x-1,y,p-3),(x,y-1,p-1),(x+1,y,p)] + for nextx,nexty,nextp in nextpos: + if isValid(matrix, n, m, nextp, nextx, nexty, visited): + path.append([nextx,nexty]) + visited.add(nextx*m + nexty) + # 由该点延伸出来的路径是否能到达终点,如果成功,则该路径是体力消耗最小的路径 + if getPath(matrix, n, m, nextp, nextx, nexty, visited, path): + return True + # 如果不成功,移除该路径,继续判断下一路径 + path.pop(-1) + visited.remove(nextx*m + nexty) + return False + +if __name__ == '__main__': + n, m, p = map(int, raw_input().split()) + matrix = [map(int, raw_input().split()) for _ in range(n)] + visited = set() + path = [[0,0]] + if getPath(matrix, n, m, p, 0, 0, visited, path): + print(','.join(map(str, path)).replace(' ', '')) + else: print('Can not escape!') \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/32.\346\234\253\345\260\2760\347\232\204\344\270\252\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/32.\346\234\253\345\260\2760\347\232\204\344\270\252\346\225\260.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/32.\346\234\253\345\260\2760\347\232\204\344\270\252\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/32.\346\234\253\345\260\2760\347\232\204\344\270\252\346\225\260.py" index b9f0066..ce339ea 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/32.\346\234\253\345\260\2760\347\232\204\344\270\252\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/32.\346\234\253\345\260\2760\347\232\204\344\270\252\346\225\260.py" @@ -1,17 +1,17 @@ -# 方法一:先算阶乘结果,再求0。算法复杂度太高 -n = int(raw_input()) -res = 1 -for i in range(1,n+1): - res *= i -count = 0 -while res%10==0: - count += 1 -print(count) - -# 方法二:0由偶数乘5得到,输入的整数的阶乘序列有几个5的倍数就有几个0 -n = int(raw_input()) -count = 0 -while n: - count += (n/5) - n /= 5 -print(count) +# 方法一:先算阶乘结果,再求0。算法复杂度太高 +n = int(raw_input()) +res = 1 +for i in range(1,n+1): + res *= i +count = 0 +while res%10==0: + count += 1 +print(count) + +# 方法二:0由偶数乘5得到,输入的整数的阶乘序列有几个5的倍数就有几个0 +n = int(raw_input()) +count = 0 +while n: + count += (n/5) + n /= 5 +print(count) diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/33.\350\277\233\345\210\266\350\275\254\346\215\242.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/33.\350\277\233\345\210\266\350\275\254\346\215\242.py" similarity index 94% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/33.\350\277\233\345\210\266\350\275\254\346\215\242.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/33.\350\277\233\345\210\266\350\275\254\346\215\242.py" index 79002dd..1a8f96d 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/33.\350\277\233\345\210\266\350\275\254\346\215\242.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/33.\350\277\233\345\210\266\350\275\254\346\215\242.py" @@ -1,17 +1,17 @@ -# 进制转换方法:除基取余,余数逆置 -a = map(int, raw_input().split()) -m, n = a[0], a[1] -s = '0123456789ABCDEF' -res = '' -flag = 0 -if m<0: - m = -m - flag = 1 -while m: - res += s[m%n] - m /= n -if flag: - res += '-' - print(res[::-1]) -else: +# 进制转换方法:除基取余,余数逆置 +a = map(int, raw_input().split()) +m, n = a[0], a[1] +s = '0123456789ABCDEF' +res = '' +flag = 0 +if m<0: + m = -m + flag = 1 +while m: + res += s[m%n] + m /= n +if flag: + res += '-' + print(res[::-1]) +else: print(res[::-1]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/34.\346\225\260\345\255\227\345\222\214\344\270\272sum\347\232\204\346\226\271\346\263\225\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/34.\346\225\260\345\255\227\345\222\214\344\270\272sum\347\232\204\346\226\271\346\263\225\346\225\260.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/34.\346\225\260\345\255\227\345\222\214\344\270\272sum\347\232\204\346\226\271\346\263\225\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/34.\346\225\260\345\255\227\345\222\214\344\270\272sum\347\232\204\346\226\271\346\263\225\346\225\260.py" index 913617a..8d53e3d 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/34.\346\225\260\345\255\227\345\222\214\344\270\272sum\347\232\204\346\226\271\346\263\225\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/34.\346\225\260\345\255\227\345\222\214\344\270\272sum\347\232\204\346\226\271\346\263\225\346\225\260.py" @@ -1,23 +1,23 @@ -# 01背包问题。与55题比较 -# 写法一 -n, m = map(int, raw_input().split()) -a = map(int, raw_input().split()) -dp = [0]*(m+1) -dp[0] = 1 -for i in a: - # 数字只能用一次,需要逆着计算,不会累加到前面结果 - for j in range(m, i-1, -1): - dp[j] += dp[j-i] -print(dp[m]) - -# 写法二 -n, m = map(int, raw_input().split()) -a = map(int, raw_input().split()) -dp = [0]*(m+1) -dp[0] = 1 -for i in a: - j = m - while j>=i: - dp[j] += dp[j-i] - j -= 1 -print(dp[m]) +# 01背包问题。与55题比较 +# 写法一 +n, m = map(int, raw_input().split()) +a = map(int, raw_input().split()) +dp = [0]*(m+1) +dp[0] = 1 +for i in a: + # 数字只能用一次,需要逆着计算,不会累加到前面结果 + for j in range(m, i-1, -1): + dp[j] += dp[j-i] +print(dp[m]) + +# 写法二 +n, m = map(int, raw_input().split()) +a = map(int, raw_input().split()) +dp = [0]*(m+1) +dp[0] = 1 +for i in a: + j = m + while j>=i: + dp[j] += dp[j-i] + j -= 1 +print(dp[m]) diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/35.\345\255\227\347\254\246\344\270\262\344\270\255\346\211\276\345\207\272\350\277\236\347\273\255\346\234\200\351\225\277\347\232\204\346\225\260\345\255\227\344\270\262.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/35.\345\255\227\347\254\246\344\270\262\344\270\255\346\211\276\345\207\272\350\277\236\347\273\255\346\234\200\351\225\277\347\232\204\346\225\260\345\255\227\344\270\262.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/35.\345\255\227\347\254\246\344\270\262\344\270\255\346\211\276\345\207\272\350\277\236\347\273\255\346\234\200\351\225\277\347\232\204\346\225\260\345\255\227\344\270\262.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/35.\345\255\227\347\254\246\344\270\262\344\270\255\346\211\276\345\207\272\350\277\236\347\273\255\346\234\200\351\225\277\347\232\204\346\225\260\345\255\227\344\270\262.py" index ee03e6d..f0fe80b 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/35.\345\255\227\347\254\246\344\270\262\344\270\255\346\211\276\345\207\272\350\277\236\347\273\255\346\234\200\351\225\277\347\232\204\346\225\260\345\255\227\344\270\262.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/35.\345\255\227\347\254\246\344\270\262\344\270\255\346\211\276\345\207\272\350\277\236\347\273\255\346\234\200\351\225\277\347\232\204\346\225\260\345\255\227\344\270\262.py" @@ -1,21 +1,21 @@ -# 方法一:正则匹配 -import re -s = raw_input() -str_list = re.findall(r'\d+', s) -print(max(str_list, key=len)) - -# 方法二:遍历字符串,记录长度与字符串 -s = raw_input() -cur_len = max_len = 0 -cur_str = max_str = '' -for i,v in enumerate(s): - if v>='0' and v<='9': - cur_len += 1 - cur_str += v - if cur_len > max_len: - max_len = cur_len - max_str = cur_str - else: - cur_len = 0 - cur_str = '' +# 方法一:正则匹配 +import re +s = raw_input() +str_list = re.findall(r'\d+', s) +print(max(str_list, key=len)) + +# 方法二:遍历字符串,记录长度与字符串 +s = raw_input() +cur_len = max_len = 0 +cur_str = max_str = '' +for i,v in enumerate(s): + if v>='0' and v<='9': + cur_len += 1 + cur_str += v + if cur_len > max_len: + max_len = cur_len + max_str = cur_str + else: + cur_len = 0 + cur_str = '' print(max_str) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/36.n\344\270\252\346\225\260\351\207\214\346\234\200\345\260\217\347\232\204k\344\270\252.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/36.n\344\270\252\346\225\260\351\207\214\346\234\200\345\260\217\347\232\204k\344\270\252.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/36.n\344\270\252\346\225\260\351\207\214\346\234\200\345\260\217\347\232\204k\344\270\252.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/36.n\344\270\252\346\225\260\351\207\214\346\234\200\345\260\217\347\232\204k\344\270\252.py" index 69ebdcb..db68c74 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/36.n\344\270\252\346\225\260\351\207\214\346\234\200\345\260\217\347\232\204k\344\270\252.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/36.n\344\270\252\346\225\260\351\207\214\346\234\200\345\260\217\347\232\204k\344\270\252.py" @@ -1,14 +1,14 @@ -# 写法一:字符串追加 -a = [int(i) for i in raw_input().split()] -k, n = a[-1], a[:-1] -n.sort() -res = '' -for i in range(k-1): - res += str(n[i])+' ' -res += str(n[i+1]) -print(res) - -# 写法二:取字符串一段区间 -a = list(map(int, raw_input().split())) -k, n = a[-1], a[:-1] +# 写法一:字符串追加 +a = [int(i) for i in raw_input().split()] +k, n = a[-1], a[:-1] +n.sort() +res = '' +for i in range(k-1): + res += str(n[i])+' ' +res += str(n[i+1]) +print(res) + +# 写法二:取字符串一段区间 +a = list(map(int, raw_input().split())) +k, n = a[-1], a[:-1] print(' '.join(list(map(str, sorted(n)[:k])))) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/37.n\344\270\252\346\225\260\351\207\214\345\207\272\347\216\260\346\254\241\346\225\260\345\244\247\344\272\216\347\255\211\344\272\216\351\225\277\345\272\246\344\270\200\345\215\212\347\232\204\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/37.n\344\270\252\346\225\260\351\207\214\345\207\272\347\216\260\346\254\241\346\225\260\345\244\247\344\272\216\347\255\211\344\272\216\351\225\277\345\272\246\344\270\200\345\215\212\347\232\204\346\225\260.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/37.n\344\270\252\346\225\260\351\207\214\345\207\272\347\216\260\346\254\241\346\225\260\345\244\247\344\272\216\347\255\211\344\272\216\351\225\277\345\272\246\344\270\200\345\215\212\347\232\204\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/37.n\344\270\252\346\225\260\351\207\214\345\207\272\347\216\260\346\254\241\346\225\260\345\244\247\344\272\216\347\255\211\344\272\216\351\225\277\345\272\246\344\270\200\345\215\212\347\232\204\346\225\260.py" index 4da8788..b5cbba1 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/37.n\344\270\252\346\225\260\351\207\214\345\207\272\347\216\260\346\254\241\346\225\260\345\244\247\344\272\216\347\255\211\344\272\216\351\225\277\345\272\246\344\270\200\345\215\212\347\232\204\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/37.n\344\270\252\346\225\260\351\207\214\345\207\272\347\216\260\346\254\241\346\225\260\345\244\247\344\272\216\347\255\211\344\272\216\351\225\277\345\272\246\344\270\200\345\215\212\347\232\204\346\225\260.py" @@ -1,7 +1,7 @@ -# 利用列表的count()方法 -n = list(raw_input().split()) -m = set(n) -for i in m: - if n.count(i) >= len(n)/2: - print(i) +# 利用列表的count()方法 +n = list(raw_input().split()) +m = set(n) +for i in m: + if n.count(i) >= len(n)/2: + print(i) break \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/38.\345\200\222\347\275\256\345\255\227\347\254\246\344\270\262.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/38.\345\200\222\347\275\256\345\255\227\347\254\246\344\270\262.py" similarity index 100% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/38.\345\200\222\347\275\256\345\255\227\347\254\246\344\270\262.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/38.\345\200\222\347\275\256\345\255\227\347\254\246\344\270\262.py" diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/39.\345\210\240\351\231\244\345\205\254\345\205\261\345\255\227\347\254\246.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/39.\345\210\240\351\231\244\345\205\254\345\205\261\345\255\227\347\254\246.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/39.\345\210\240\351\231\244\345\205\254\345\205\261\345\255\227\347\254\246.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/39.\345\210\240\351\231\244\345\205\254\345\205\261\345\255\227\347\254\246.py" index c8e2a05..6492ad8 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/39.\345\210\240\351\231\244\345\205\254\345\205\261\345\255\227\347\254\246.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/39.\345\210\240\351\231\244\345\205\254\345\205\261\345\255\227\347\254\246.py" @@ -1,8 +1,8 @@ -# 在新字符串中追加需要的字符 -s1 = raw_input() -s2 = raw_input() -s = '' -for i in s1: - if i not in s2: - s += i +# 在新字符串中追加需要的字符 +s1 = raw_input() +s2 = raw_input() +s = '' +for i in s1: + if i not in s2: + s += i print(s) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/40.\346\261\202\345\222\214.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/40.\346\261\202\345\222\214.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/40.\346\261\202\345\222\214.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/40.\346\261\202\345\222\214.py" index daf6aae..785d997 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/40.\346\261\202\345\222\214.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/40.\346\261\202\345\222\214.py" @@ -1,11 +1,11 @@ -# 递归 -n, m = map(int, raw_input().split()) -res = [] -def getResult(n, m, res, begin): - if m==0: - print(' '.join(res)) - for i in range(begin, n+1): - res.append(str(i)) - getResult(n, m-i, res, i+1) - res.pop() +# 递归 +n, m = map(int, raw_input().split()) +res = [] +def getResult(n, m, res, begin): + if m==0: + print(' '.join(res)) + for i in range(begin, n+1): + res.append(str(i)) + getResult(n, m-i, res, i+1) + res.pop() getResult(n, m, res, 1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/41.\347\274\226\347\240\201.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/41.\347\274\226\347\240\201.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/41.\347\274\226\347\240\201.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/41.\347\274\226\347\240\201.py" index 01bb650..a37041b 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/41.\347\274\226\347\240\201.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/41.\347\274\226\347\240\201.py" @@ -1,10 +1,10 @@ -s = raw_input() -n1 = 25**3+25**2+25+1 -n2 = 25**2+25+1 -n3 = 25+1 -n4 = 1 -n = [n1,n2,n3,n4] -count = len(s)-1 -for i in range(len(s)): - count += n[i]*(ord(s[i])-ord('a')) +s = raw_input() +n1 = 25**3+25**2+25+1 +n2 = 25**2+25+1 +n3 = 25+1 +n4 = 1 +n = [n1,n2,n3,n4] +count = len(s)-1 +for i in range(len(s)): + count += n[i]*(ord(s[i])-ord('a')) print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/42.\346\270\270\346\210\217\344\273\273\345\212\241\346\240\207\350\256\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/42.\346\270\270\346\210\217\344\273\273\345\212\241\346\240\207\350\256\260.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/42.\346\270\270\346\210\217\344\273\273\345\212\241\346\240\207\350\256\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/42.\346\270\270\346\210\217\344\273\273\345\212\241\346\240\207\350\256\260.py" index 4fc10ef..09db756 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/42.\346\270\270\346\210\217\344\273\273\345\212\241\346\240\207\350\256\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/42.\346\270\270\346\210\217\344\273\273\345\212\241\346\240\207\350\256\260.py" @@ -1,9 +1,9 @@ -# 判断条件即可 -a, b = map(int, raw_input().split()) -if (a>=1 and a<=1024) and (b>=1 and b<=1024): - if a==b: - print(1) - else: - print(0) -else: +# 判断条件即可 +a, b = map(int, raw_input().split()) +if (a>=1 and a<=1024) and (b>=1 and b<=1024): + if a==b: + print(1) + else: + print(0) +else: print(-1) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/43.\347\264\240\346\225\260\345\257\271.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/43.\347\264\240\346\225\260\345\257\271.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/43.\347\264\240\346\225\260\345\257\271.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/43.\347\264\240\346\225\260\345\257\271.py" index de7d250..00a82db 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/43.\347\264\240\346\225\260\345\257\271.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/43.\347\264\240\346\225\260\345\257\271.py" @@ -1,18 +1,18 @@ -import math -n = int(raw_input()) -s = [] -for i in range(2, n): - flag = 1 - # 判断是否为质数 - for j in range(2, int(math.sqrt(i))+1): - if i%j==0: - flag = 0 - break - if flag: - s.append(i) -count = 0 -# 判断质数的和是否等于输入的数 -for i,v in enumerate(s): - if n-v in s[i:]: - count += 1 +import math +n = int(raw_input()) +s = [] +for i in range(2, n): + flag = 1 + # 判断是否为质数 + for j in range(2, int(math.sqrt(i))+1): + if i%j==0: + flag = 0 + break + if flag: + s.append(i) +count = 0 +# 判断质数的和是否等于输入的数 +for i,v in enumerate(s): + if n-v in s[i:]: + count += 1 print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/44.geohash\347\274\226\347\240\201.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/44.geohash\347\274\226\347\240\201.py" similarity index 94% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/44.geohash\347\274\226\347\240\201.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/44.geohash\347\274\226\347\240\201.py" index 1668705..1f49d3c 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/44.geohash\347\274\226\347\240\201.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/44.geohash\347\274\226\347\240\201.py" @@ -1,14 +1,14 @@ -# 与中间数比较即可 -n = int(raw_input()) -left = -90 -right = 90 -res = '' -while right-left>3: - mid = int((left+right)/2.0) - if n >= mid: - res += '1' - left = mid - else: - res += '0' - right = mid +# 与中间数比较即可 +n = int(raw_input()) +left = -90 +right = 90 +res = '' +while right-left>3: + mid = int((left+right)/2.0) + if n >= mid: + res += '1' + left = mid + else: + res += '0' + right = mid print(res) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/45.\346\234\200\345\274\272\345\244\247\350\204\221.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/45.\346\234\200\345\274\272\345\244\247\350\204\221.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/45.\346\234\200\345\274\272\345\244\247\350\204\221.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/45.\346\234\200\345\274\272\345\244\247\350\204\221.py" index 610faec..4cc326c 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/45.\346\234\200\345\274\272\345\244\247\350\204\221.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/45.\346\234\200\345\274\272\345\244\247\350\204\221.py" @@ -1,18 +1,18 @@ -# 将序列的正反方向进行判断 -s, s1, s2 = raw_input(), raw_input(), raw_input() -f = b = False -for i,s in enumerate([s, s[::-1]]): - if (s1 in s) and (s2 in s[s.index(s1)+len(s1):]): - if i == 0: - f = True - if i == 1: - b = True -if f: - if b: - print('both') - else: - print('forward') -elif b: - print('backward') -else: +# 将序列的正反方向进行判断 +s, s1, s2 = raw_input(), raw_input(), raw_input() +f = b = False +for i,s in enumerate([s, s[::-1]]): + if (s1 in s) and (s2 in s[s.index(s1)+len(s1):]): + if i == 0: + f = True + if i == 1: + b = True +if f: + if b: + print('both') + else: + print('forward') +elif b: + print('backward') +else: print('invalid') \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/46.\345\244\264\346\235\241\346\240\241\346\213\233.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/46.\345\244\264\346\235\241\346\240\241\346\213\233.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/46.\345\244\264\346\235\241\346\240\241\346\213\233.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/46.\345\244\264\346\235\241\346\240\241\346\213\233.py" index f0bda11..5b32736 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/46.\345\244\264\346\235\241\346\240\241\346\213\233.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/46.\345\244\264\346\235\241\346\240\241\346\213\233.py" @@ -1,20 +1,20 @@ -# 案例: -# 2,14,15,30,42,100 -# 2,14,15,30,100,100 - -n = int(raw_input()) -d = map(int, raw_input().split()) -# 添加两个数防止循环过程数组下标越界,也要防止干扰原始数据 -d += [121, 121] -d.sort() -i = count = 0 -while i=d[i+1]: - if d[i]+20>=d[i+2]: - j += 2 - else: - j += 1 - count += (3-j) - i += j +# 案例: +# 2,14,15,30,42,100 +# 2,14,15,30,100,100 + +n = int(raw_input()) +d = map(int, raw_input().split()) +# 添加两个数防止循环过程数组下标越界,也要防止干扰原始数据 +d += [121, 121] +d.sort() +i = count = 0 +while i=d[i+1]: + if d[i]+20>=d[i+2]: + j += 2 + else: + j += 1 + count += (3-j) + i += j print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/47.\345\274\202\346\210\226.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/47.\345\274\202\346\210\226.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/47.\345\274\202\346\210\226.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/47.\345\274\202\346\210\226.py" index c8af60b..1c5912f 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/47.\345\274\202\346\210\226.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/47.\345\274\202\346\210\226.py" @@ -1,16 +1,16 @@ -# 暴力破解。超过限制的内存 -from itertools import combinations -n, m = map(int, raw_input().split()) -A = map(int, raw_input().split()) -nums = list(combinations(A, 2)) -count = 0 -for num in nums: - x, y = num[0], num[1] - if x^y > m: - count += 1 -print(count) - -# 调用函数写法 -from itertools import combinations -n, m = map(int, raw_input().split()) -print(len(list(filter(lambda x: x>m, map(lambda x:x[0]^x[1], combinations(list(map(int, raw_input().split())), 2)))))) +# 暴力破解。超过限制的内存 +from itertools import combinations +n, m = map(int, raw_input().split()) +A = map(int, raw_input().split()) +nums = list(combinations(A, 2)) +count = 0 +for num in nums: + x, y = num[0], num[1] + if x^y > m: + count += 1 +print(count) + +# 调用函数写法 +from itertools import combinations +n, m = map(int, raw_input().split()) +print(len(list(filter(lambda x: x>m, map(lambda x:x[0]^x[1], combinations(list(map(int, raw_input().split())), 2)))))) diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/48.\345\255\227\345\205\270\345\272\217.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/48.\345\255\227\345\205\270\345\272\217.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/48.\345\255\227\345\205\270\345\272\217.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/48.\345\255\227\345\205\270\345\272\217.py" index 8a062b6..3273c25 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/48.\345\255\227\345\205\270\345\272\217.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/48.\345\255\227\345\205\270\345\272\217.py" @@ -1,27 +1,27 @@ -# 暴力破解。超过限制的内存 -n, m = map(int, raw_input().split()) -s = [str(i) for i in range(1, n+1)] -s.sort() -print(s[m-1]) - -# 将字典序视作一个树,寻找m次则循环m次来找寻结果 -# 如果在这个区间内则M在这个区间内查找,让i+1一个一个查找,否则让梯度乘以10向上查找 -# 第一个while循环是判断是否查到这个位置,第二个则是写出num在这个区间内有多少个数 -n, m = map(int, raw_input().split()) -result = 1 -m -= 1 -while m: - count = 0 - start = result - end = result + 1 - while start <= n: - count += min(end, n+1) - start - start *= 10 - end *= 10 - if count > m: - result *= 10 - m -= 1 - else: - result += 1 - m -= count +# 暴力破解。超过限制的内存 +n, m = map(int, raw_input().split()) +s = [str(i) for i in range(1, n+1)] +s.sort() +print(s[m-1]) + +# 将字典序视作一个树,寻找m次则循环m次来找寻结果 +# 如果在这个区间内则M在这个区间内查找,让i+1一个一个查找,否则让梯度乘以10向上查找 +# 第一个while循环是判断是否查到这个位置,第二个则是写出num在这个区间内有多少个数 +n, m = map(int, raw_input().split()) +result = 1 +m -= 1 +while m: + count = 0 + start = result + end = result + 1 + while start <= n: + count += min(end, n+1) - start + start *= 10 + end *= 10 + if count > m: + result *= 10 + m -= 1 + else: + result += 1 + m -= count print(result) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/49.\344\277\235\345\215\253\346\226\271\346\241\210.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/49.\344\277\235\345\215\253\346\226\271\346\241\210.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/49.\344\277\235\345\215\253\346\226\271\346\241\210.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/49.\344\277\235\345\215\253\346\226\271\346\241\210.py" index 5e9d2bd..0cf951f 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/49.\344\277\235\345\215\253\346\226\271\346\241\210.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/49.\344\277\235\345\215\253\346\226\271\346\241\210.py" @@ -1,18 +1,18 @@ -# 类似62题 -# 将字符串拼接类比环 -try: - n = input() - h = map(int,raw_input().split()) - if n>10000: - raise Exception - s = h+h - l = [] - for i in range(n): - t = s[i+1] - for j in range(i+2, i+n-1): - if s[i]>=t and s[j]>=t and [i,j%n] not in l and [j%n,i] not in l: - l.append([i,j%n]) - t = s[j] - print(len(l)+n) -except: +# 类似62题 +# 将字符串拼接类比环 +try: + n = input() + h = map(int,raw_input().split()) + if n>10000: + raise Exception + s = h+h + l = [] + for i in range(n): + t = s[i+1] + for j in range(i+2, i+n-1): + if s[i]>=t and s[j]>=t and [i,j%n] not in l and [j%n,i] not in l: + l.append([i,j%n]) + t = s[j] + print(len(l)+n) +except: print(499999500000) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/50.\351\233\206\345\220\210.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/50.\351\233\206\345\220\210.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/50.\351\233\206\345\220\210.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/50.\351\233\206\345\220\210.py" index 9274186..57aa077 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/50.\351\233\206\345\220\210.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/50.\351\233\206\345\220\210.py" @@ -1,6 +1,6 @@ -# 连接,去重,排序 -n, m = raw_input().split() -a = map(int, raw_input().split()) -b = map(int, raw_input().split()) -c = map(str, sorted(list(set(a+b)))) +# 连接,去重,排序 +n, m = raw_input().split() +a = map(int, raw_input().split()) +b = map(int, raw_input().split()) +c = map(str, sorted(list(set(a+b)))) print(' '.join(c)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/51.\350\277\233\345\210\266\345\235\207\345\200\274.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/51.\350\277\233\345\210\266\345\235\207\345\200\274.py" similarity index 94% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/51.\350\277\233\345\210\266\345\235\207\345\200\274.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/51.\350\277\233\345\210\266\345\235\207\345\200\274.py" index b3cfef6..f218553 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/51.\350\277\233\345\210\266\345\235\207\345\200\274.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/51.\350\277\233\345\210\266\345\235\207\345\200\274.py" @@ -1,16 +1,16 @@ -# 1、数字位求和 2、最大公约数 -n = int(raw_input()) -s = 0 -for i in range(2, n): - t = n - while t: - s += (t%i) - t /= i -f = s -r = m = n-2 -# r:余数 f:公约数 -while r: - f, r = r, f%r -s /= f -m /= f +# 1、数字位求和 2、最大公约数 +n = int(raw_input()) +s = 0 +for i in range(2, n): + t = n + while t: + s += (t%i) + t /= i +f = s +r = m = n-2 +# r:余数 f:公约数 +while r: + f, r = r, f%r +s /= f +m /= f print('%d/%d'%(s,m)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/52.\345\271\270\350\277\220\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/52.\345\271\270\350\277\220\346\225\260.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/52.\345\271\270\350\277\220\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/52.\345\271\270\350\277\220\346\225\260.py" index ee25414..86d5161 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/52.\345\271\270\350\277\220\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/52.\345\271\270\350\277\220\346\225\260.py" @@ -1,15 +1,15 @@ -n = int(raw_input()) -count = 0 -# 遍历每个数 -for i in range(1, n+1): - s1 = s2 = 0 - # 数的每一位累加 - for j in str(i): - s1 += int(j) - # 二进制位累加 - while i: - s2 += (i%2) - i /= 2 - if s1 == s2: - count += 1 +n = int(raw_input()) +count = 0 +# 遍历每个数 +for i in range(1, n+1): + s1 = s2 = 0 + # 数的每一位累加 + for j in str(i): + s1 += int(j) + # 二进制位累加 + while i: + s2 += (i%2) + i /= 2 + if s1 == s2: + count += 1 print(count) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/53.\344\270\242\345\244\261\347\232\204\344\270\211\344\270\252\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/53.\344\270\242\345\244\261\347\232\204\344\270\211\344\270\252\346\225\260.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/53.\344\270\242\345\244\261\347\232\204\344\270\211\344\270\252\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/53.\344\270\242\345\244\261\347\232\204\344\270\211\344\270\252\346\225\260.py" index 5e34bdd..2720bea 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/53.\344\270\242\345\244\261\347\232\204\344\270\211\344\270\252\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/53.\344\270\242\345\244\261\347\232\204\344\270\211\344\270\252\346\225\260.py" @@ -1,6 +1,6 @@ -# 求差集 -n1 = map(int, raw_input().split()) -n2 = [i for i in range(1, 10001)] -n3 = sorted(list(map(str, set(n2).difference(set(n1))))) -res = int(''.join(n3))%7 +# 求差集 +n1 = map(int, raw_input().split()) +n2 = [i for i in range(1, 10001)] +n3 = sorted(list(map(str, set(n2).difference(set(n1))))) +res = int(''.join(n3))%7 print(res) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/54.\347\275\221\346\240\274\350\265\260\346\263\225\346\225\260\347\233\256.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/54.\347\275\221\346\240\274\350\265\260\346\263\225\346\225\260\347\233\256.py" similarity index 98% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/54.\347\275\221\346\240\274\350\265\260\346\263\225\346\225\260\347\233\256.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/54.\347\275\221\346\240\274\350\265\260\346\263\225\346\225\260\347\233\256.py" index b5d718b..ab63ccf 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/54.\347\275\221\346\240\274\350\265\260\346\263\225\346\225\260\347\233\256.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/54.\347\275\221\346\240\274\350\265\260\346\263\225\346\225\260\347\233\256.py" @@ -1,11 +1,11 @@ -# 动态规划: -# 对于x*Y网格,dp[i][j]表示(i,j)位置一共有多少种走法, -# 由于只能向右和向下走,所以第一列和第一行所有位置的走法都是1,即dp[i][0]=1,dp[0][j]=1, -# 对于其他位置,走法应该等于其左边格点的走法与其上面格点的走法之和,dp[i][j]=dp[i-1][j]+dp[i][j-1] - -row, col = map(int, raw_input().split()) -result = [[1 for _ in range(col)] for _ in range(row)] -for i in range(row): - for j in range(col): - result[i][j] = result[i-1][j] + result[i][j-1] +# 动态规划: +# 对于x*Y网格,dp[i][j]表示(i,j)位置一共有多少种走法, +# 由于只能向右和向下走,所以第一列和第一行所有位置的走法都是1,即dp[i][0]=1,dp[0][j]=1, +# 对于其他位置,走法应该等于其左边格点的走法与其上面格点的走法之和,dp[i][j]=dp[i-1][j]+dp[i][j-1] + +row, col = map(int, raw_input().split()) +result = [[1 for _ in range(col)] for _ in range(row)] +for i in range(row): + for j in range(col): + result[i][j] = result[i-1][j] + result[i][j-1] print(result[-1][-1]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/55.\346\213\274\345\207\221\351\235\242\351\242\235.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/55.\346\213\274\345\207\221\351\235\242\351\242\235.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/55.\346\213\274\345\207\221\351\235\242\351\242\235.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/55.\346\213\274\345\207\221\351\235\242\351\242\235.py" index 5638174..3a8e7eb 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/55.\346\213\274\345\207\221\351\235\242\351\242\235.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/55.\346\213\274\345\207\221\351\235\242\351\242\235.py" @@ -1,8 +1,8 @@ -# 完全背包问题。与34题比较。 -N = int(raw_input()) -dp = [1]*(N+1) -for c in [5, 10, 20, 50, 100]: - # 硬币足够多,顺着计算,累加前面的结果 - for i in range(c, N+1): - dp[i] += dp[i-c] +# 完全背包问题。与34题比较。 +N = int(raw_input()) +dp = [1]*(N+1) +for c in [5, 10, 20, 50, 100]: + # 硬币足够多,顺着计算,累加前面的结果 + for i in range(c, N+1): + dp[i] += dp[i-c] print(dp[-1]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/56.\346\225\264\346\225\260\345\212\240\346\263\225.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/56.\346\225\264\346\225\260\345\212\240\346\263\225.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/56.\346\225\264\346\225\260\345\212\240\346\263\225.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/56.\346\225\264\346\225\260\345\212\240\346\263\225.py" index 6d9642a..ac2bc2f 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/56.\346\225\264\346\225\260\345\212\240\346\263\225.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/56.\346\225\264\346\225\260\345\212\240\346\263\225.py" @@ -1,6 +1,6 @@ -# 非数字字符转化为整数会抛异常 -a, b = raw_input().split() -try: - print(int(a)+int(b)) -except: +# 非数字字符转化为整数会抛异常 +a, b = raw_input().split() +try: + print(int(a)+int(b)) +except: print('error') \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/57.filename.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/57.filename.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/57.filename.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/57.filename.py" index 190ec80..689acbb 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/57.filename.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/57.filename.py" @@ -1,6 +1,6 @@ -# 文件扩展名以'.'开始 -s = raw_input() -if '.' not in s: - print('null') -else: +# 文件扩展名以'.'开始 +s = raw_input() +if '.' not in s: + print('null') +else: print(s[(s.index('.')+1):]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/58.\351\205\222\345\272\227\344\273\267\346\240\274.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/58.\351\205\222\345\272\227\344\273\267\346\240\274.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/58.\351\205\222\345\272\227\344\273\267\346\240\274.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/58.\351\205\222\345\272\227\344\273\267\346\240\274.py" index 2ef4b69..0da5925 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/58.\351\205\222\345\272\227\344\273\267\346\240\274.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/58.\351\205\222\345\272\227\344\273\267\346\240\274.py" @@ -1,21 +1,21 @@ -# 用一个数组存放每个日期的价格,然后遍历数组,价格不同时则分段 -import sys -min_, max_ = 100000, 0 -values = [0]*100000 -for line in sys.stdin.readlines(): - l, r, v = map(int, line.split()) - if l < min_: - min_ = l - if r > max_: - max_ = r - for i in range(l, r+1): - values[i] = v -res = '[' + str(min_) + ', ' -for i in range(min_+1, max_+1): - if values[i] != values[i-1]: - if values[i-1] != 0: - res += str(i-1) + ', ' + str(values[i-1]) + '],' - if i < max_ and values[i] != 0: - res += '[' + str(i) + ', ' -res += str(max_) + ', ' + str(values[max_]) + ']' +# 用一个数组存放每个日期的价格,然后遍历数组,价格不同时则分段 +import sys +min_, max_ = 100000, 0 +values = [0]*100000 +for line in sys.stdin.readlines(): + l, r, v = map(int, line.split()) + if l < min_: + min_ = l + if r > max_: + max_ = r + for i in range(l, r+1): + values[i] = v +res = '[' + str(min_) + ', ' +for i in range(min_+1, max_+1): + if values[i] != values[i-1]: + if values[i-1] != 0: + res += str(i-1) + ', ' + str(values[i-1]) + '],' + if i < max_ and values[i] != 0: + res += '[' + str(i) + ', ' +res += str(max_) + ', ' + str(values[max_]) + ']' print(res) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/59.\350\272\253\344\273\275\350\257\201\345\210\206\347\273\204.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/59.\350\272\253\344\273\275\350\257\201\345\210\206\347\273\204.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/59.\350\272\253\344\273\275\350\257\201\345\210\206\347\273\204.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/59.\350\272\253\344\273\275\350\257\201\345\210\206\347\273\204.py" index d758d91..2283ba7 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/59.\350\272\253\344\273\275\350\257\201\345\210\206\347\273\204.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/59.\350\272\253\344\273\275\350\257\201\345\210\206\347\273\204.py" @@ -1,8 +1,8 @@ -# 502104 19880330 8324 按照此格式划分 -s = raw_input() -if len(s)<6: - print(s) -elif len(s)<14: - print(s[:6] + ' ' + s[6:]) -else: +# 502104 19880330 8324 按照此格式划分 +s = raw_input() +if len(s)<6: + print(s) +elif len(s)<14: + print(s[:6] + ' ' + s[6:]) +else: print(s[:6] + ' ' + s[6:14] + ' ' + s[14:]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/60.\347\273\237\350\256\241\345\255\227\347\254\246.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/60.\347\273\237\350\256\241\345\255\227\347\254\246.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/60.\347\273\237\350\256\241\345\255\227\347\254\246.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/60.\347\273\237\350\256\241\345\255\227\347\254\246.py" index 2c66ef0..efa63c0 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/60.\347\273\237\350\256\241\345\255\227\347\254\246.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/60.\347\273\237\350\256\241\345\255\227\347\254\246.py" @@ -1,11 +1,11 @@ -# 使用字典存放并累加字符个数 -s = raw_input() -d = {} -for i in s: - if i in d: - d[i] += 1 - else: - d[i] = 1 - if d[i] == 3 and i.isalpha(): - print(i) +# 使用字典存放并累加字符个数 +s = raw_input() +d = {} +for i in s: + if i in d: + d[i] += 1 + else: + d[i] = 1 + if d[i] == 3 and i.isalpha(): + print(i) break \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/61.\344\277\235\347\225\231\346\234\200\345\244\247\347\232\204\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/61.\344\277\235\347\225\231\346\234\200\345\244\247\347\232\204\346\225\260.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/61.\344\277\235\347\225\231\346\234\200\345\244\247\347\232\204\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/61.\344\277\235\347\225\231\346\234\200\345\244\247\347\232\204\346\225\260.py" index b00651d..9e050e9 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/61.\344\277\235\347\225\231\346\234\200\345\244\247\347\232\204\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/61.\344\277\235\347\225\231\346\234\200\345\244\247\347\232\204\346\225\260.py" @@ -1,15 +1,15 @@ -num = raw_input() -count = int(raw_input()) -stack = [] -for i in num: - while stack and count: - # 后面的数比前面大时,则前面的数弹出,保证从左到右以由大到小的顺序排列 - if stack[-1] < i: - stack.pop() - count -= 1 - else: - break - stack.append(i) -if count: - stack = stack[:-count] +num = raw_input() +count = int(raw_input()) +stack = [] +for i in num: + while stack and count: + # 后面的数比前面大时,则前面的数弹出,保证从左到右以由大到小的顺序排列 + if stack[-1] < i: + stack.pop() + count -= 1 + else: + break + stack.append(i) +if count: + stack = stack[:-count] print(''.join(stack)) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/62.\345\275\251\350\211\262\345\256\235\347\237\263\351\241\271\351\223\276.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/62.\345\275\251\350\211\262\345\256\235\347\237\263\351\241\271\351\223\276.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/62.\345\275\251\350\211\262\345\256\235\347\237\263\351\241\271\351\223\276.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/62.\345\275\251\350\211\262\345\256\235\347\237\263\351\241\271\351\223\276.py" index 622b1fb..b53fc28 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/62.\345\275\251\350\211\262\345\256\235\347\237\263\351\241\271\351\223\276.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/62.\345\275\251\350\211\262\345\256\235\347\237\263\351\241\271\351\223\276.py" @@ -1,15 +1,15 @@ -# 类似49题 -# 将字符串拼接类比环 - -# 寻找每个包含'ABCDE'的区间,最终排序得出最小的区间 -s = raw_input() -s2 = s+s -res = [] -i, j = 0, 5 -while j left: - if i+step >= n: - print(count[i]) - break - for j in range(left+1, step+i+1): - count[j] = count[i] + 1 - left = step + i - -# 写法二 -inf = float('inf') -a, b = int(raw_input()), list(map(int,raw_input().split())) -dp = [inf]*10000 -dp[0] = 0 -for i in range(1,a+1): - for j in range(i): - if b[j]+j >= i: - dp[i] = min(dp[i], dp[j]+1) +# 动态规划 + +# 写法一 +n = int(raw_input()) +steps = map(int, raw_input().split()) +count = [1]*n +left = 0 +for i in range(n): + step = steps[i] + if step == 0 and left == i: + print(-1) + break + if i+step > left: + if i+step >= n: + print(count[i]) + break + for j in range(left+1, step+i+1): + count[j] = count[i] + 1 + left = step + i + +# 写法二 +inf = float('inf') +a, b = int(raw_input()), list(map(int,raw_input().split())) +dp = [inf]*10000 +dp[0] = 0 +for i in range(1,a+1): + for j in range(i): + if b[j]+j >= i: + dp[i] = min(dp[i], dp[j]+1) print(-1 if dp[a]==inf else dp[a]) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/64.\346\261\202\346\225\260\345\210\227\347\232\204\345\222\214.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/64.\346\261\202\346\225\260\345\210\227\347\232\204\345\222\214.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/64.\346\261\202\346\225\260\345\210\227\347\232\204\345\222\214.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/64.\346\261\202\346\225\260\345\210\227\347\232\204\345\222\214.py" index b331df7..022fc53 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/64.\346\261\202\346\225\260\345\210\227\347\232\204\345\222\214.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/64.\346\261\202\346\225\260\345\210\227\347\232\204\345\222\214.py" @@ -1,7 +1,7 @@ -import math -n, m = map(int, raw_input().split()) -s = 0 -for i in range(m): - s += n - n = math.sqrt(n) +import math +n, m = map(int, raw_input().split()) +s = 0 +for i in range(m): + s += n + n = math.sqrt(n) print('%.2f'%s) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/65.\346\260\264\344\273\231\350\212\261\346\225\260.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/65.\346\260\264\344\273\231\350\212\261\346\225\260.py" similarity index 95% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/65.\346\260\264\344\273\231\350\212\261\346\225\260.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/65.\346\260\264\344\273\231\350\212\261\346\225\260.py" index dd45d04..0e67af5 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/65.\346\260\264\344\273\231\350\212\261\346\225\260.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/65.\346\260\264\344\273\231\350\212\261\346\225\260.py" @@ -1,14 +1,14 @@ -# 取出数的每一位,按要求计算 -l = list(map(int, raw_input().split())) -m, n = l[0], l[1] -res = [] -for i in range(m, n+1): - a = i%10 - b = i/10%10 - c = i/100 - if i == a**3+b**3+c**3: - res.append(i) -if not res: - print('no') -else: +# 取出数的每一位,按要求计算 +l = list(map(int, raw_input().split())) +m, n = l[0], l[1] +res = [] +for i in range(m, n+1): + a = i%10 + b = i/10%10 + c = i/100 + if i == a**3+b**3+c**3: + res.append(i) +if not res: + print('no') +else: print(' '.join(map(str, res))) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/66.\347\224\265\350\257\235\345\217\267\347\240\201\345\210\206\350\272\253.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/66.\347\224\265\350\257\235\345\217\267\347\240\201\345\210\206\350\272\253.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/66.\347\224\265\350\257\235\345\217\267\347\240\201\345\210\206\350\272\253.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/66.\347\224\265\350\257\235\345\217\267\347\240\201\345\210\206\350\272\253.py" index 1cb0f95..703c0a1 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/66.\347\224\265\350\257\235\345\217\267\347\240\201\345\210\206\350\272\253.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/66.\347\224\265\350\257\235\345\217\267\347\240\201\345\210\206\350\272\253.py" @@ -1,18 +1,18 @@ -# 由每个单词独有的字母求出该数有几个 -n=int(raw_input()) -data=[] -for i in range(n): - data.append(raw_input()) -for d in data: - zero=d.count('Z') - two=d.count('W') - four = d.count('U') - six = d.count('X') - eight = d.count('G') - - one = d.count('O') - zero - two - four - three = d.count('H') - eight - five = d.count('F') - four - seven = d.count('V') - five - nine = d.count('I')-six-five-eight +# 由每个单词独有的字母求出该数有几个 +n=int(raw_input()) +data=[] +for i in range(n): + data.append(raw_input()) +for d in data: + zero=d.count('Z') + two=d.count('W') + four = d.count('U') + six = d.count('X') + eight = d.count('G') + + one = d.count('O') - zero - two - four + three = d.count('H') - eight + five = d.count('F') - four + seven = d.count('V') - five + nine = d.count('I')-six-five-eight print('0'*eight + '1'*nine + '2'*zero + '3'*one + '4'*two + '5'*three + '6'*four + '7'*five + '8'*six + '9'*seven) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/67.\345\217\245\345\255\220\345\217\215\350\275\254.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/67.\345\217\245\345\255\220\345\217\215\350\275\254.py" similarity index 98% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/67.\345\217\245\345\255\220\345\217\215\350\275\254.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/67.\345\217\245\345\255\220\345\217\215\350\275\254.py" index bc88d94..271bbff 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/67.\345\217\245\345\255\220\345\217\215\350\275\254.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/67.\345\217\245\345\255\220\345\217\215\350\275\254.py" @@ -1,2 +1,2 @@ -n = list(raw_input().split()) +n = list(raw_input().split()) print(' '.join(n[::-1])) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/68.\346\240\221\347\232\204\351\253\230\345\272\246.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/68.\346\240\221\347\232\204\351\253\230\345\272\246.py" similarity index 97% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/68.\346\240\221\347\232\204\351\253\230\345\272\246.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/68.\346\240\221\347\232\204\351\253\230\345\272\246.py" index c01201b..faeb653 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/68.\346\240\221\347\232\204\351\253\230\345\272\246.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/68.\346\240\221\347\232\204\351\253\230\345\272\246.py" @@ -1,9 +1,9 @@ -n = int(raw_input()) -# {结点:[总高度,子结点数]} -tree = {'0':[1, 0]} -for _ in range(n-1): - father, child = raw_input().split() - if father in tree and tree[father][1]<2: - tree[father][1] += 1 - tree[child] = [tree[father][0]+1, 0] +n = int(raw_input()) +# {结点:[总高度,子结点数]} +tree = {'0':[1, 0]} +for _ in range(n-1): + father, child = raw_input().split() + if father in tree and tree[father][1]<2: + tree[father][1] += 1 + tree[child] = [tree[father][0]+1, 0] print(max(node[0] for node in tree.values())) \ No newline at end of file diff --git "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/69.\346\225\260\344\270\262.py" "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/69.\346\225\260\344\270\262.py" similarity index 96% rename from "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/69.\346\225\260\344\270\262.py" rename to "2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/69.\346\225\260\344\270\262.py" index 7501b01..0b70eae 100644 --- "a/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273/69.\346\225\260\344\270\262.py" +++ "b/2017\346\240\241\346\213\233\347\234\237\351\242\230\347\274\226\347\250\213\351\242\230\346\261\207\346\200\273_Python/69.\346\225\260\344\270\262.py" @@ -1,15 +1,15 @@ -# 冒泡排序 -n = int(raw_input()) -m = list(raw_input().split()) -for i in range(n-1): - for j in range(n-1-i): - if m[j]+m[j+1] < m[j+1]+m[j]: - m[j], m[j+1] = m[j+1], m[j] -print(''.join(m)) - -# sort()方法排序 -n = int(raw_input()) -m = raw_input().split() -# 默认由小到大排序,反转则由大到小排序 -m.sort(cmp=lambda x,y: cmp(x+y, y+x), reverse=True) +# 冒泡排序 +n = int(raw_input()) +m = list(raw_input().split()) +for i in range(n-1): + for j in range(n-1-i): + if m[j]+m[j+1] < m[j+1]+m[j]: + m[j], m[j+1] = m[j+1], m[j] +print(''.join(m)) + +# sort()方法排序 +n = int(raw_input()) +m = raw_input().split() +# 默认由小到大排序,反转则由大到小排序 +m.sort(cmp=lambda x,y: cmp(x+y, y+x), reverse=True) print(''.join(m)) \ No newline at end of file diff --git a/README.md b/README.md index f018d2f..162d475 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # 原题链接 +- [codetop](https://codetop.cc/home) - [leetcode](https://leetcode-cn.com/problemset/algorithms/) -- [热题HOT100](https://leetcode-cn.com/problemset/leetcode-hot-100/) +- [热题HOT100](https://leetcode-cn.com/problem-list/2cktkvj/) - [剑指Offer](https://www.nowcoder.com/ta/coding-interviews) - [2017校招真题编程题汇总](https://www.nowcoder.com/ta/2017test) - [2019校招真题编程题汇总](https://www.nowcoder.com/ta/2019test) - [数据库SQL实战](https://www.nowcoder.com/ta/sql?query=&asc=true&order=&page=1) +- [十大经典排序算法动画与解析](https://mp.weixin.qq.com/s/vn3KiV-ez79FmbZ36SX9lg) diff --git a/leetcode_Java/DoneTitle.txt b/leetcode_Java/DoneTitle.txt new file mode 100644 index 0000000..89301e1 --- /dev/null +++ b/leetcode_Java/DoneTitle.txt @@ -0,0 +1,183 @@ +1. 两数之和 +2. 两数相加 +3. 无重复字符的最长子串 +4. 寻找两个有序数组的中位数 +5. 最长回文子串 +8. 字符串转换整数 (atoi) +10. 正则表达式匹配 +11. 盛最多水的容器 +14. 最长公共前缀 +15. 三数之和 +17. 电话号码的字母组合 +19. 删除链表的倒数第 N 个结点 +20. 有效的括号 +21. 合并两个有序链表 +22. 括号生成 +23. 合并K个升序链表 +24. 两两交换链表中的节点 +25. K 个一组翻转链表 +29. 两数相除 +31. 下一个排列 +32. 最长有效括号 +33. 搜索旋转排序数组 +34. 在排序数组中查找元素的第一个和最后一个位置 +37. 解数独 +39. 组合总和 +40. 组合总和 II +41. 缺失的第一个正数 +42. 接雨水 +43. 字符串相乘 +46. 全排列 +47. 全排列 II +48. 旋转图像 +51. N 皇后 +53. 最大子数组和 +54. 螺旋矩阵 +55. 跳跃游戏 +56. 合并区间 +59. 螺旋矩阵 II +62. 不同路径 +64. 最小路径和 +69. x 的平方根 +70. 爬楼梯 +72. 编辑距离 +75. 颜色分类 +76. 最小覆盖子串 +77. 组合 +78. 子集 +79. 单词搜索 +81. 搜索旋转排序数组 II +82. 删除排序链表中的重复元素 II +83. 删除排序链表中的重复元素 +84. 柱状图中最大的矩形 +85. 最大矩形 +88. 合并两个有序数组 +90. 子集 II +92. 反转链表 II +93. 复原 IP 地址 +94. 二叉树的中序遍历 +96. 不同的二叉搜索树 +98. 验证二叉搜索树 +101. 对称二叉树 +102. 二叉树的层序遍历 +103. 二叉树的锯齿形层序遍历 +104. 二叉树的最大深度 +105. 从前序与中序遍历序列构造二叉树 +110. 平衡二叉树 +112. 路径总和 +113. 路径总和 II +114. 二叉树展开为链表 +115. 不同的子序列 +121. 买卖股票的最佳时机 +122. 买卖股票的最佳时机 II +123. 买卖股票的最佳时机 III +124. 二叉树中的最大路径和 +128. 最长连续序列 +129. 求根节点到叶节点数字之和 +130. 被围绕的区域 +131. 分割回文串 +136. 只出现一次的数字 +138. 复制带随机指针的链表 +139. 单词拆分 +141. 环形链表 +142. 环形链表 II +143. 重排链表 +144. 二叉树的前序遍历 +145. 二叉树的后序遍历 +146. LRU 缓存 +148. 排序链表 +151. 颠倒字符串中的单词 +152. 乘积最大子数组 +153. 寻找旋转排序数组中的最小值 +154. 寻找旋转排序数组中的最小值 II +155. 最小栈 +160. 相交链表 +162. 寻找峰值 +165. 比较版本号 +169. 多数元素 +188. 买卖股票的最佳时机 IV +198. 打家劫舍 +199. 二叉树的右视图 +200. 岛屿数量 +203. 移除链表元素 +206. 反转链表 +207. 课程表 +208. 实现 Trie (前缀树) +215. 数组中的第K个最大元素 +216. 组合总和 III +221. 最大正方形 +224. 基本计算器 +226. 翻转二叉树 +227. 基本计算器 II +232. 用栈实现队列 +234. 回文链表 +236. 二叉树的最近公共祖先 +238. 除自身以外数组的乘积 +239. 滑动窗口最大值 +240. 搜索二维矩阵 II +279. 完全平方数 +283. 移动零 +287. 寻找重复数 +297. 二叉树的序列化与反序列化 +300. 最长上升子序列 +301. 删除无效的括号 +303. 区域和检索 - 数组不可变 +304. 二维区域和检索 - 矩阵不可变 +309. 最佳买卖股票时机含冷冻期 +312. 戳气球 +316. 去除重复字母 +322. 零钱兑换 +337. 打家劫舍 III +338. 比特位计数 +347. 前 K 个高频元素 +392. 判断子序列 +394. 字符串解码 +399. 除法求值 +402. 移掉 K 位数字 +406. 根据身高重建队列 +407. 接雨水 II +415. 字符串相加 +416. 分割等和子集 +437. 路径总和 III +438. 找到字符串中所有字母异位词 +448. 找到所有数组中消失的数字 +461. 汉明距离 +463. 岛屿的周长 +468. 验证IP地址 +470. 用 Rand7() 实现 Rand10() +474. 一和零 +491. 递增子序列 +494. 目标和 +496. 下一个更大元素 I +503. 下一个更大元素 II +509. 斐波那契数 +516. 最长回文子序列 +518. 零钱兑换 II +538. 把二叉搜索树转换为累加树 +543. 二叉树的直径 +560. 和为 K 的子数组 +581. 最短无序连续子数组 +583. 两个字符串的删除操作 +589. N叉树的前序遍历 +617. 合并二叉树 +621. 任务调度器 +647. 回文子串 +662. 二叉树最大宽度 +674. 最长连续递增序列 +695. 岛屿的最大面积 +698. 划分为k个相等的子集 +704. 二分查找 +707. 设计链表 +712. 两个字符串的最小ASCII删除和 +714. 买卖股票的最佳时机含手续费 +718. 最长重复子数组 +739. 每日温度 +867. 转置矩阵 +901. 股票价格跨度 +968. 监控二叉树 +1020. 飞地的数量 +1035. 不相交的线 +1081. 不同字符的最小子序列 +1143. 最长公共子序列 +1254. 统计封闭岛屿的数目 +1905. 统计子岛屿 \ No newline at end of file diff --git a/leetcode_Java/DoneType.txt b/leetcode_Java/DoneType.txt new file mode 100644 index 0000000..2a9735d --- /dev/null +++ b/leetcode_Java/DoneType.txt @@ -0,0 +1,239 @@ +分类目录 +一、树 +二、回溯 +三、动态规划 +四、链表 +五、深度优先搜索 +六、单调/栈/队列 +七、数组 +八、字符串 +九、位运算 +十、数学 +十一、图 +十二、二分查找 + + +一、树 +94. 二叉树的中序遍历(递归,迭代,栈,列表,哈希表,莫里斯遍历) +96. 不同的二叉搜索树(递归,动态规划) +98. 验证二叉搜索树(递归,迭代) +101. 对称二叉树(递归,迭代) +102. 二叉树的层序遍历(递归,迭代) +103. 二叉树的锯齿形层序遍历(递归,迭代) +104. 二叉树的最大深度(递归,迭代) +105. 从前序与中序遍历序列构造二叉树(递归,迭代) +110. 平衡二叉树(递归) +112. 路径总和(递归,迭代) +113. 路径总和 II(递归,回溯,迭代) +114. 二叉树展开为链表(迭代) +124. 二叉树中的最大路径和(递归) +129. 求根节点到叶节点数字之和(递归,迭代) +144. 二叉树的前序遍历(递归,迭代) +145. 二叉树的后序遍历(递归,迭代) +199. 二叉树的右视图(迭代) +226. 翻转二叉树(递归,迭代) +236. 二叉树的最近公共祖先(递归) +297. 二叉树的序列化与反序列化(递归,迭代) +437. 路径总和 III(递归) +538. 把二叉搜索树转换为累加树(递归) +543. 二叉树的直径(递归) +589. N叉树的前序遍历(递归,迭代) +617. 合并二叉树(递归,迭代) +662. 二叉树最大宽度(递归,迭代) +968. 监控二叉树(递归) + +二、回溯 +17. 电话号码的字母组合 +37. 解数独 +39. 组合总和 +40. 组合总和 II +46. 全排列 +47. 全排列 II +51. N 皇后 +77. 组合 +78. 子集 +79. 单词搜索 +90. 子集 II +93. 复原 IP 地址 +131. 分割回文串 +216. 组合总和 III +301. 删除无效的括号 +491. 递增子序列 +494. 目标和 +698. 划分为k个相等的子集 + + +三、动态规划 +5. 最长回文子串 +10. 正则表达式匹配 +22. 括号生成 +32. 最长有效括号 +42. 接雨水 +53. 最大子数组和 +55. 跳跃游戏 +62. 不同路径 +64. 最小路径和 +70. 爬楼梯 +72. 编辑距离 +96. 不同的二叉搜索树 +115. 不同的子序列 +121. 买卖股票的最佳时机 +122. 买卖股票的最佳时机 II +123. 买卖股票的最佳时机 III +139. 单词拆分 +152. 乘积最大子数组 +188. 买卖股票的最佳时机 IV +198. 打家劫舍 +221. 最大正方形 +279. 完全平方数 +300. 最长上升子序列 +309. 最佳买卖股票时机含冷冻期 +312. 戳气球 +322. 零钱兑换 +337. 打家劫舍 III +392. 判断子序列 +416. 分割等和子集 +474. 一和零 +494. 目标和 +509. 斐波那契数 +516. 最长回文子序列 +518. 零钱兑换 II +583. 两个字符串的删除操作 +647. 回文子串 +674. 最长连续递增序列 +712. 两个字符串的最小ASCII删除和 +714. 买卖股票的最佳时机含手续费 +718. 最长重复子数组 +1035. 不相交的线 +1143. 最长公共子序列 + + +四、链表 +2. 两数相加(迭代模拟) +19. 删除链表的倒数第 N 个结点(递归,快慢指针,栈,计数) +21. 合并两个有序链表(递归,迭代) +23. 合并K个升序链表(顺序合并,分治合并) +24. 两两交换链表中的节点(递归,迭代) +25. K 个一组翻转链表(多指针) +82. 删除排序链表中的重复元素 II(递归,双指针) +83. 删除排序链表中的重复元素 +92. 反转链表 II(多指针) +138. 复制带随机指针的链表(递归,迭代,哈希表) +141. 环形链表(快慢指针,列表,哈希表) +142. 环形链表 II(快慢指针,列表,哈希表) +143. 重排链表(双指针,快慢指针,递归) +146. LRU 缓存(双向链表,哈希表) +148. 排序链表(归并排序,优先级队列,列表) +160. 相交链表(双指针,列表) +203. 移除链表元素(迭代,递归) +206. 反转链表(迭代,递归,建链表,栈,插入) +234. 回文链表(快慢指针,递归,列表) +707. 设计链表(单链表,双链表) + + +五、深度优先搜索 +79. 单词搜索 +130. 被围绕的区域 +200. 岛屿数量 +463. 岛屿的周长 +695. 岛屿的最大面积 +1020. 飞地的数量 +1254. 统计封闭岛屿的数目 +1905. 统计子岛屿 + + +六、单调/栈/队列 +84. 柱状图中最大的矩形(单调递增栈) +85. 最大矩形(单调递增栈,暴力,动态规划) +155. 最小栈 +232. 用栈实现队列 +316. 去除重复字母(单调递增栈) +402. 移掉 K 位数字(单调递增栈) +407. 接雨水 II(优先级队列) +496. 下一个更大元素 I(单调递减栈) +503. 下一个更大元素 II(单调递减栈) +739. 每日温度(单调递减栈) +901. 股票价格跨度(单调递减栈) +1081. 不同字符的最小子序列(单调递增栈) + + +七、数组 +1. 两数之和(哈希表) +4. 寻找两个有序数组的中位数(排序,双指针,二分查找) +11. 盛最多水的容器(双指针) +15. 三数之和(三指针) +31. 下一个排列(置换) +41. 缺失的第一个正数(置换,排序,集合) +48. 旋转图像(置换) +54. 螺旋矩阵(四指针) +56. 合并区间(二维数组排序) +59. 螺旋矩阵 II(四指针) +75. 颜色分类(单指针,双指针) +88. 合并两个有序数组(排序,双指针) +128. 最长连续序列(集合,排序) +136. 只出现一次的数字(哈希表,列表,位运算) +169. 多数元素(排序,哈希表,投票,计数,分治) +215. 数组中的第K个最大元素(快速排序,堆排序) +238. 除自身以外数组的乘积(前缀和) +239. 滑动窗口最大值(单调递减双端队列) +240. 搜索二维矩阵 II(二分查找) +283. 移动零(双指针) +287. 寻找重复数(哈希表,快慢指针,二分查找,位运算) +303. 区域和检索 - 数组不可变(前缀和) +304. 二维区域和检索 - 矩阵不可变(前缀和) +347. 前 K 个高频元素(快速排序,堆排序,优先级队列) +406. 根据身高重建队列(二维数组排序) +448. 找到所有数组中消失的数字(计数,集合,置换) +560. 和为 K 的子数组(前缀和,哈希表) +581. 最短无序连续子数组(排序,双指针) +621. 任务调度器(桶填充) +867. 转置矩阵(置换) + + +八、字符串 +3. 无重复字符的最长子串(滑动窗口) +8. 字符串转换整数 (atoi) +14. 最长公共前缀(横向比较,纵向比较) +20. 有效的括号(字符替换,哈希表) +32. 最长有效括号(栈,贪心,计数,动态规划) +43. 字符串相乘(模拟相乘,位置规律) +76. 最小覆盖子串(双指针,滑动窗口) +151. 颠倒字符串中的单词(分割反转,双指针,双端队列) +165. 比较版本号(双指针,字符串分割) +208. 实现 Trie (前缀树) +224. 基本计算器(双栈) +227. 基本计算器 II(双栈,哈希表) +394. 字符串解码(栈) +415. 字符串相加(模拟相加) +438. 找到字符串中所有字母异位词(滑动窗口,双指针) +468. 验证IP地址(分割校验) + + +九、位运算 +287. 寻找重复数 +338. 比特位计数 +461. 汉明距离 + + +十、数学 +470. 用 Rand7() 实现 Rand10()(拒绝采样) + + +十一、图 +207. 课程表(拓扑排序) +399. 除法求值(并查集) + + +十二、二分查找 +4. 寻找两个有序数组的中位数(排序,双指针,二分查找) +29. 两数相除(二分查找) +33. 搜索旋转排序数组(二分查找) +34. 在排序数组中查找元素的第一个和最后一个位置(二分查找) +81. 搜索旋转排序数组 II(二分查找) +69. x 的平方根(二分查找) +153. 寻找旋转排序数组中的最小值(二分查找) +154. 寻找旋转排序数组中的最小值 II(二分查找) +162. 寻找峰值(二分查找) +240. 搜索二维矩阵 II(二分查找) +287. 寻找重复数(哈希表,快慢指针,二分查找,位运算) +704. 二分查找 \ No newline at end of file diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution001.java" b/leetcode_Java/Solution0001.java similarity index 58% rename from "\347\203\255\351\242\230HOT100_Java/Solution001.java" rename to leetcode_Java/Solution0001.java index 10ef6e6..45f8b93 100644 --- "a/\347\203\255\351\242\230HOT100_Java/Solution001.java" +++ b/leetcode_Java/Solution0001.java @@ -1,22 +1,24 @@ -package HOT100; - -import java.util.HashMap; - -// 两数之和 -public class Solution001 { - public int[] twoSum(int[] nums, int target) { - HashMap map = new HashMap<>(); - int[] res = new int[2]; - - for (int i = 0; i < nums.length; i++) { - if (map.containsKey(target - nums[i])) { - res[0] = i; - res[1] = map.get(target - nums[i]); - return res; - } else { - map.put(nums[i], i); - } - } - return res; - } -} +// 1. 两数之和 + + +/* +思路: +1、中间数据使用HashMap存放,记录值和索引。结果数据使用整型数组存放 +2、输入的数组使用for循环遍历,通过目标值相减的方式获取输入数组中和HashMap中满足条件的两个整数,获取其索引存入结果数组 + */ +class Solution { + public int[] twoSum(int[] nums, int target) { + HashMap map = new HashMap<>(); + int[] res = new int[2]; + for (int i = 0; i < nums.length; i++) { + if (map.containsKey(target - nums[i])) { + res[0] = i; + res[1] = map.get(target - nums[i]); + return res; + } else { + map.put(nums[i], i); + } + } + return res; + } +} diff --git a/leetcode_Java/Solution0002.java b/leetcode_Java/Solution0002.java new file mode 100644 index 0000000..ba7101a --- /dev/null +++ b/leetcode_Java/Solution0002.java @@ -0,0 +1,38 @@ +// 2. 两数相加 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +1、同时遍历两个链表,对应位置的值相加,且加上进位值,计算新的进位值,创建新的节点 +2、两个链表长度不同,则短链表后面默认为0 +3、链表遍历结束后,如果进位值为1,需要再加一个节点 + */ +class Solution { + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode head = new ListNode(0); + ListNode cur = head; + int add = 0; + while (l1 != null || l2 != null || add != 0) { + int l1Val = l1 != null ? l1.val : 0; + int l2Val = l2 != null ? l2.val : 0; + int num = l1Val + l2Val + add; + add = num / 10; + cur.next = new ListNode(num % 10); + cur = cur.next; + l1 = l1 != null ? l1.next : null; + l2 = l2 != null ? l2.next : null; + } + return head.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0003.java b/leetcode_Java/Solution0003.java new file mode 100644 index 0000000..4eb1102 --- /dev/null +++ b/leetcode_Java/Solution0003.java @@ -0,0 +1,54 @@ +// 3. 无重复字符的最长子串 + + +/* +索引定位收缩左区间: +1、HashMap保存滑动窗口中的字符的索引 +2、如果右指针移动过程新的字符 出现 在滑动窗口中,则更新左指针位置 +3、更新当前字符在HashMap中的索引 +4、右指针每移动一次后,计算新窗口的长度,比较并保存最大长度 + */ +class Solution { + public int lengthOfLongestSubstring(String s) { + int maxLen = 0, start = 0; + Map map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (map.containsKey(c)) { + start = Math.max(map.get(c) + 1, start); + } + map.put(c, i); + maxLen = Math.max(maxLen, i - start + 1); + } + return maxLen; + } +} + + +/* +左指针右移收缩左区间: +1、HashMap保存滑动窗口中的字符的出现次数 +2、如果右指针移动过程新的字符 没有 在滑动窗口中,则将字符添加到HashMap中,次数记为1 +3、如果右指针移动过程新的字符 出现 在滑动窗口中,则移动左指针直到同样该字符的下一位,移动过程指向的字符在HashMap中出现次数减1 +4、右指针每移动一次后,计算新窗口的长度,比较并保存最大长度 + */ +class Solution { + public int lengthOfLongestSubstring(String s) { + int maxLen = 0, start = 0; + Map map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (map.getOrDefault(c, 0) == 0) { + map.put(c, 1); + } else { + while (s.charAt(start) != c) { + map.put(s.charAt(start), map.get(s.charAt(start)) -1); + start++; + } + start++; + } + maxLen = Math.max(maxLen, i - start + 1); + } + return maxLen; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0004.java b/leetcode_Java/Solution0004.java new file mode 100644 index 0000000..21ae390 --- /dev/null +++ b/leetcode_Java/Solution0004.java @@ -0,0 +1,141 @@ +// 4. 寻找两个有序数组的中位数 + + +/* +数组合并,排序,取中间 + */ +public class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + // Arrays.copyOf(源数组, 复制长度) + int[] nums = Arrays.copyOf(nums1, nums1.length + nums2.length); + // System.arraycopy(源数组, 源数组起始索引, 目标数组, 目标数组起始索引, 复制长度) + System.arraycopy(nums2, 0, nums, nums1.length, nums2.length); + Arrays.sort(nums); + + if (nums.length % 2 == 0) + return ((float) nums[nums.length / 2 - 1] + nums[nums.length / 2]) / 2; + else + return (float) nums[nums.length / 2]; + } +} + + +/* +逻辑同上 + */ +class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int n = nums1.length + nums2.length; + int[] nums3 = new int[n]; + int k = 0; + for (int i = 0; i < nums1.length; i++) { + nums3[k] = nums1[i]; + k++; + } + for (int j = 0; j < nums2.length; j++) { + nums3[k] = nums2[j]; + k++; + } + Arrays.sort(nums3); + if (n % 2 == 0) { + int num1 = nums3[n / 2]; + int num2 = nums3[n / 2 - 1]; + return (num1 + num2) / 2.0; + } else { + return nums3[n / 2]; + } + } +} + + +/* +双指针:遍历比较两个数组元素,根据奇偶个数找到整体中间位置,计算中位数 + */ +class Solution { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int m = nums1.length, n = nums2.length; + int len = m + n; + int left = -1, right = - 1; + int index1 = 0, index2 = 0; + for (int i = 0; i <= len / 2; i++) { + left = right; + if (index1 < m && (index2 >= n || nums1[index1] < nums2[index2])) { + right = nums1[index1++]; + } else { + right = nums2[index2++]; + } + } + if (len % 2 == 0) { + return (left + right) / 2.0; + } + return right; + } +} + + +/* +二分查找: +1、一个长度为 m 的数组,有 0 到 m 总共 m + 1 个位置可以切。我们把数组 A 和数组 B 分别在 i 和 j 进行切割 +2、将 i 的左边和 j 的左边组合成「左半部分」,将 i 的右边和 j 的右边组合成「右半部分」 + 1)当 A 数组和 B 数组的总长度是偶数时,如果我们能够保证 左半部分的长度等于右半部分 i+j = m-i + n-j,也就是 j = (m+n)/2 - i, + 且左半部分最大的值小于等于右半部分最小的值,max(A[i-1],B[j-1])) <= min(A[i],B[j])) + 那么 中位数 = (左半部分最大值 + 右半部分最小值) / 2 = (max(A[i-1],B[j-1]) + min(A[i],B[j])) / 2 + 2)当 A 数组和 B 数组的总长度是奇数时,如果我们能够保证 左半部分的长度比右半部分大 1, i+j = m-i + n-j + 1,也就是 j = (m+n+1)/2 - i, + 且左半部分最大的值小于等于右半部分最小的值,max(A[i-1],B[j-1])) <= min(A[i],B[j])) + 那么 中位数 = 左半部分最大值 = max(A[i-1],B[j-1]) +3、增加 i 的方式用二分,初始化 i 为中间的值,然后减半找中间的,直到找到答案 +4、时间复杂度:我们对较短的数组进行了二分查找,所以时间复杂度是 O(log(min(m,n)) + 空间复杂度:只有一些固定的变量,和数组长度无关,所以空间复杂度是 O(1) + +A: 2 4 6 | 8 10 12 14 + iMin i iMax +B: 1 5 8 10 11 | 12 12 15 + j +================================= +A: 2 4 6 8 10 | 12 14 + iMin i iMax +B: 1 5 8 | 10 11 12 12 15 + j + */ +class Solution { + public double findMedianSortedArrays(int[] A, int[] B) { + int m = A.length; + int n = B.length; + if (m > n) { + return findMedianSortedArrays(B, A); + } + int iMin = 0, iMax = m; + while (iMin <= iMax) { + int i = (iMin + iMax) / 2; + int j = (m + n + 1) / 2 - i; + if (j != 0 && i != m && B[j - 1] > A[i]) { + iMin = i + 1; + } else if (i != 0 && j != n && A[i - 1] > B[j]) { + iMax = i - 1; + } else { + int maxLeft = 0; + if (i == 0) { + maxLeft = B[j - 1]; + } else if (j == 0) { + maxLeft = A[i - 1]; + } else { + maxLeft = Math.max(A[i - 1], B[j - 1]); + } + if ((m + n) % 2 == 1) { + return maxLeft; + } + + int minRight = 0; + if (i == m) { + minRight = B[j]; + } else if (j == n) { + minRight = A[i]; + } else { + minRight = Math.min(B[j], A[i]); + } + return (maxLeft + minRight) / 2.0; + } + } + return 0.0; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0005.java b/leetcode_Java/Solution0005.java new file mode 100644 index 0000000..010732e --- /dev/null +++ b/leetcode_Java/Solution0005.java @@ -0,0 +1,129 @@ +// 5. 最长回文子串 + + +/* +暴力破解:列举所有的子串,判断是否为回文串,保存最长的回文串 + */ +class Solution { + public String longestPalindrome(String s) { + int len = s.length(); + if (len < 2) { + return s; + } + int maxLen = 0; + String res = ""; + for (int l = 0; l < len; l++) { + for (int r = l + maxLen; r <= len; r++) { + String sub = s.substring(l, r); + int subLen = sub.length(); + if (isPalindrome(sub) && subLen > maxLen) { + res = sub; + maxLen = subLen; + } + } + } + return res; + } + + private boolean isPalindrome(String s) { + int l = 0, r = s.length() - 1; + while (l < r) { + if (s.charAt(l) != s.charAt(r)) { + return false; + } + l++; + r--; + } + return true; + } + + // 方法同上,使用for替代while + private boolean isPalindrome(String s) { + for (int l = 0, r = s.length() - 1; l < r; l++, r--) { + if (s.charAt(l) != s.charAt(r)) { + return false; + } + } + return true; + } +} + + +/* +中心扩散: +1、遍历字符,以当前字符为中心向两边扩散,包括奇数和偶数回文串两种中心,得到当前中心的回文串长度 +2、比较并记录所有中心的最长回文串长度和对应起点,最后截取并返回最长回文子串 + */ +class Solution { + public String longestPalindrome(String s) { + int len = s.length(); + if (len < 2) { + return s; + } + int maxLen = 1; + int start = 0; + for (int i = 0; i < len - 1; i++) { + int oddLen = expandAroudCenter(s, i, i); + int evenLen = expandAroudCenter(s, i, i + 1); + int curMaxLen = Math.max(oddLen, evenLen); + if (curMaxLen > maxLen) { + maxLen = curMaxLen; + start = i - (maxLen - 1) / 2; + } + } + return s.substring(start, start + maxLen); + } + + private int expandAroudCenter(String s, int l, int r) { + while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { + l--; + r++; + } + return r - l - 1; + } +} + + +/* +与“647.回文子串”相似 +动态规划:动态规划是暴力破解的优化,两者同样需要遍历列举判断所有子串是否为回文串,区别是暴力破解每次都要对子串单独处理判断是否为回文串,动态规划可以利用之前记录的子串结果直接判断当前子串是否为回文串 +1、题目:给你一个字符串 s,找到 s 中最长的回文子串。 +2、题目简化:求字符串s的最长回文子串。要先判断子串是否为回文串,再从回文子串中取最长。 +3、定义dp数组:dp[l][r]表示子串s[l,r]是否为回文子串,l是左区间,r是右区间 +4、初始化: + 1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)boolean数组创建时,默认值是false,只需要标记为true的地方即可。可以初始化dp数组 dp[i][i] = true,表示1个字符是回文 +5、状态转移方程:dp[l][r] = (s[l] == s[r]) and (r - l < 3 or dp[l + 1][r - 1]) + 1)s[l] == s[r] 表示首尾两个字符相等 + 2)r - l < 3 表示去掉首尾后剩余0或1个字符时仍是回文。作用包含了1个字符是回文,所以不用初始化dp数组单个字符为true + 3)dp[l + 1][r - 1] 表示去掉首尾后的区间是否回文 +6、遍历dp数组填表:一个for遍历子串的右区间,另一个for循环遍历子串的左区间,根据状态转移方程推断计算未知结果并填表,当是回文串时比较并记录最长长度和左右区间位置 +7、返回结果:根据遍历时记录的最长回文子串左右区间位置,截取字符串s得到最长回文子串 + +s: b a b a d + ↑ ↑ + l r + */ +class Solution { + public String longestPalindrome(String s) { + int n = s.length(); + if (n < 2) { + return s; + } + int maxLen = 1, start = 0, end = 0; + boolean[][] dp = new boolean[n][n]; + for (int r = 1; r < n; r++) { + for (int l = 0; l < r; l++) { + if (s.charAt(l) == s.charAt(r) && (r - l < 3 || dp[l + 1][r - 1])) { + dp[l][r] = true; + if (r - l + 1 > maxLen) { + maxLen = r - l + 1; + start = l; + end = r; + } + } + } + } + return s.substring(start, end + 1); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0008.java b/leetcode_Java/Solution0008.java new file mode 100644 index 0000000..05fb60e --- /dev/null +++ b/leetcode_Java/Solution0008.java @@ -0,0 +1,30 @@ +// 8. 字符串转换整数 (atoi) + + +/* +1、遍历去掉空格 +2、判断是否有+-符号,有则记录sign +3、遍历数字,如果算上当前数字后超过整型最大值,则根据sign标志直接返回结果,否则更新结果将当前数字加入最低位 + if语句另一写法 if ((long) res * 10 + digit > Integer.MAX_VALUE) {} +4、根据sign标志返回结果 + */ +class Solution { + public int myAtoi(String s) { + int n = s.length(), res = 0, index = 0, sign = 1; + char[] array = s.toCharArray(); + while (index < n && array[index] == ' ') { + index++; + } + if (index < n && (array[index] == '-' || array[index] == '+')) { + sign = array[index++] == '-' ? -1 : 1; + } + while (index < n && array[index] >= '0' && array[index] <= '9') { + int digit = array[index++] - '0'; + if (res > (Integer.MAX_VALUE - digit) / 10) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + res = res * 10 + digit; + } + return res * sign; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0010.java b/leetcode_Java/Solution0010.java new file mode 100644 index 0000000..8f659b4 --- /dev/null +++ b/leetcode_Java/Solution0010.java @@ -0,0 +1,79 @@ +// 10. 正则表达式匹配 + + +/* +1、定义dp数组:dp[i][j] 表示 s 的前 i 个字符是否能被 p 的前 j 个字符匹配 +2、初始化 + 1)s为空,p为空,能匹配 + 2)p为空,s不为空,不能匹配。boolean数组默认值为false,无需处理 + 3)s为空,p不为空,由于*可以匹配0个字符,所以可能匹配 +3、状态转移方程 + 1)s[i]是{字母},p[j]是{字母,点,星} + 2)s[i]字母 与 p[j]字母:两者相等则dp[i][j]看前一项即可,所以dp[i][j] = dp[i-1][j-1]。两者不等则不能匹配 + 3)s[i]字母 与 p[j]点:点能配任何一个字母,所以两者必然相等,所以dp[i][j]看前一项即可,所以dp[i][j] = dp[i-1][j-1] + 4)s[i]字母 与 p[j]星:星代表零个或多个前面的那一个元素 + ① 若为0个,匹配0次的情况,则代表删掉了p[j-1]和p[j],所以此时dp[i][j] = dp[i][j-2] + ③ 若为多个,匹配1次或多次的情况,如果s[i] == p[j-1] || p[j-1] == '.',即s的末尾字符与p的末尾前一字符匹配, + 那么可以忽略s的末尾字符,因为p的末尾可以匹配1个或多个,此时dp[i][j] = dp[i-1][j] +4、遍历dp数组填表:第一个for循环遍历字符串s,第二个for循环遍历字符串p +5、返回结果:最后一个状态就是结果 + +======== 3-2 ========= +s = "abc", p = "abc" + ↑ ↑ + i j +======== 3-3 ========= +s = "abc", p = "ab." + ↑ ↑ + i j +======== 3-4-1 ======= +s = "a", p = "ab*" + ↑ ↑ + i j +======== 3-4-2 ======= +s = "acc", p = "ac*" + ↑ ↑ + i j +s = "acc", p = "ac*" + ↑ ↑ + i j +s = "acc", p = "ac*" + ↑ ↑ + i j +======== 3-4-2 ======= +s = "acc", p = "a.*" + ↑ ↑ + i j + */ +class Solution { + public boolean isMatch(String s, String p) { + if (s == null || p == null) { + return false; + } + int m = s.length(), n = p.length(); + boolean[][] dp = new boolean[m + 1][n + 1]; + dp[0][0] = true; + for (int i = 2; i <= n; i += 2) { + if (p.charAt(i - 1) == '*') { + dp[0][i] = dp[0][i - 2]; + } + } + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + char sc = s.charAt(i - 1); + char pc = p.charAt(j - 1); + char pcPre = p.charAt(j - 2); + if (sc == pc || pc == '.') { + dp[i][j] = dp[i - 1][j - 1]; + } else if (pc == '*') { + if (dp[i][j - 2]) { + dp[i][j] = true; + } else if (sc == pcPre || pcPre == '.') { + dp[i][j] = dp[i - 1][j]; + } + } + } + } + return dp[m][n]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0011.java b/leetcode_Java/Solution0011.java new file mode 100644 index 0000000..60c9908 --- /dev/null +++ b/leetcode_Java/Solution0011.java @@ -0,0 +1,20 @@ +// 11. 盛最多水的容器 + + +/* +双指针:初始化左右指针,面积 = 柱子距离 * 矮柱子高度,然后矮柱子指针向中间移动一步,争取更高的高度,继续计算面积,记录最大面积 + */ +class Solution { + public int maxArea(int[] height) { + int l = 0, r = height.length - 1, maxArea = 0; + while (l < r) { + maxArea = Math.max(maxArea, (r - l) * Math.min(height[l], height[r])); + if (height[l] < height[r]) { + l++; + } else { + r--; + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0014.java b/leetcode_Java/Solution0014.java new file mode 100644 index 0000000..86e70cc --- /dev/null +++ b/leetcode_Java/Solution0014.java @@ -0,0 +1,60 @@ +// 14. 最长公共前缀 + + +/* +横向比较: +1、当字符串数组长度为 0 时则公共前缀为空,直接返回 +2、令第一个字符串为最长公共前缀,进行初始化 +3、第一个for循环遍历数组,第二个while循环遍历字符 + 即横向比较,遍历后面的字符串,依次将其与第一个字符串进行比较,两两找出公共前缀并截取第一个字符串,最终结果即为最长公共前缀 +4、如果查找过程第一个字符串截取后为空,则后面的字符串不用判断了,直接返回 + */ +class Solution { + public String longestCommonPrefix(String[] strs) { + int n = strs.length; + if (n == 0) { + return ""; + } + String firstStr = strs[0]; + for (int i = 1; i < n; i++) { + int j = 0; + String curStr = strs[i]; + while (j < firstStr.length() && j < curStr.length() && firstStr.charAt(j) == curStr.charAt(j)) { + j++; + } + firstStr = firstStr.substring(0, j); + if (firstStr.equals("")) { + return firstStr; + } + } + return firstStr; + } +} + + +/* +纵向比较: +1、当字符串数组长度为 0 时则公共前缀为空,直接返回 +2、第一个for循环遍历字符,第二个for循环遍历数组。即纵向比较同一位置上 其他字符串的字符 是否与 第一个字符串的字符 相同 + 相同则继续往后判断,遍历结束表示全部相同,返回第一个字符串 + 越界或不同则结束判断,然后第一个字符串截取出最长公共前缀 + */ +class Solution { + public String longestCommonPrefix(String[] strs) { + int n = strs.length; + if (n == 0) { + return ""; + } + String firstStr = strs[0]; + int m = firstStr.length(); + for (int i = 0; i < m; i++) { + for (int j = 1; j < n; j++) { + String curStr = strs[j]; + if (i == curStr.length() || curStr.charAt(i) != firstStr.charAt(i)) { + return firstStr.substring(0, i); + } + } + } + return firstStr; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0015.java b/leetcode_Java/Solution0015.java new file mode 100644 index 0000000..713b172 --- /dev/null +++ b/leetcode_Java/Solution0015.java @@ -0,0 +1,71 @@ +// 15. 三数之和 + + +/* +数组排序后,先固定一个数,再用双指针从头尾向内移动确定另外两个数,使用HashSet对结果去重 + */ +class Solution { + public List> threeSum(int[] nums) { + int n = nums.length; + Set> set = new HashSet<>(); + Arrays.sort(nums); + for (int i = 0; i < n - 2; i++) { + int l = i + 1, r = n - 1; + while (l < r) { + if (nums[i] + nums[l] + nums[r] == 0) { + List list = new ArrayList<>(); + list.add(nums[i]); + list.add(nums[l]); + list.add(nums[r]); + set.add(list); + l++; + r--; + } else if (nums[i] + nums[l] + nums[r] < 0) { + l++; + } else { + r--; + } + } + } + List> res = new ArrayList<>(set); + return res; + } +} + + +/* +逻辑同上,有优化: +1、遍历时第一个数跟前一个相同,则跳过重复处理 +2、使用ArrayList存放结果,当有一组满足条件的三元组时,通过while循环移动指针进行去重,避免出现重复的三元组 + */ +class Solution { + public List> threeSum(int[] nums) { + int n = nums.length; + List> res = new ArrayList<>(); + Arrays.sort(nums); + for (int i = 0; i < n - 2; i++) { + if (i > 0 && nums[i] == nums[i - 1]) { + continue; + } + int l = i + 1, r = n - 1; + while (l < r) { + if (nums[i] + nums[l] + nums[r] == 0) { + res.add(Arrays.asList(nums[i], nums[l], nums[r])); + l++; + r--; + while (l < r && nums[l] == nums[l - 1]) { + l++; + } + while (l < r && nums[r] == nums[r + 1]) { + r--; + } + } else if (nums[i] + nums[l] + nums[r] < 0) { + l++; + } else { + r--; + } + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0017.java b/leetcode_Java/Solution0017.java new file mode 100644 index 0000000..55dbf27 --- /dev/null +++ b/leetcode_Java/Solution0017.java @@ -0,0 +1,118 @@ +// 17. 电话号码的字母组合 + +/* +回溯: +1、使用HashMap定义数字和字符串的对应关系。每个数字代表不同的集合,即求不同集合的子集 +2、定义全局变量res存放所有子结果,sb存放临时子结果 +3、调用递归函数,处理得到所有子结果,返回结果 +4、定义递归函数: + 1)终止条件,存储子结果 + 2)for循环遍历数字对应的字符串,选择 → 递归 → 撤销,回溯 + */ +class Solution { + private Map map = new HashMap(){{ + put('2', "abc"); + put('3', "def"); + put('4', "ghi"); + put('5', "jkl"); + put('6', "mno"); + put('7', "pqrs"); + put('8', "tuv"); + put('9', "wxyz"); + }}; + private List res = new ArrayList<>(); + private StringBuilder sb = new StringBuilder(); + + public List letterCombinations(String digits) { + if (digits == null || digits.length() == 0) { + return res; + } + backtrack(digits, 0); + return res; + } + + private void backtrack(String digits, int digitIndex) { + if (sb.length() == digits.length()) { + res.add(sb.toString()); + return; + } + String letter = map.get(digits.charAt(digitIndex)); + for (int letterIndex = 0; letterIndex < letter.length(); letterIndex++) { + sb.append(letter.charAt(letterIndex)); + backtrack(digits, digitIndex + 1); + sb.deleteCharAt(sb.length() - 1); + } + } +} + + +/* +广度优先:利用队列存放字母组合,当队列不为空且数字未遍历完,则将队列的所有字母组合拿出来,每个字母组合都拼接上数字对应的字母,然后放回队列 + */ +class Solution { + public List letterCombinations(String digits) { + if (digits == null || digits.length() == 0) { + return new ArrayList<>(); + } + Map map = new HashMap(){{ + put('2', "abc"); + put('3', "def"); + put('4', "ghi"); + put('5', "jkl"); + put('6', "mno"); + put('7', "pqrs"); + put('8', "tuv"); + put('9', "wxyz"); + }}; + Queue queue = new LinkedList<>(); + queue.offer(""); + int digitIndex = 0; + while (!queue.isEmpty() && digitIndex < digits.length()) { + int curSize = queue.size(); + while (curSize > 0) { + String str = queue.poll(); + String letter = map.get(digits.charAt(digitIndex)); + for (int letterIndex = 0; letterIndex < letter.length(); letterIndex++) { + queue.add(str + letter.charAt(letterIndex)); + } + curSize--; + } + index++; + } + return new ArrayList<>(queue); + } +} + + +/* +逻辑同上,使用for替代while + */ +class Solution { + public List letterCombinations(String digits) { + if (digits == null || digits.length() == 0) { + return new ArrayList<>(); + } + Map map = new HashMap(){{ + put('2', "abc"); + put('3', "def"); + put('4', "ghi"); + put('5', "jkl"); + put('6', "mno"); + put('7', "pqrs"); + put('8', "tuv"); + put('9', "wxyz"); + }}; + Queue queue = new LinkedList<>(); + queue.offer(""); + for (int digitIndex = 0; !queue.isEmpty() && digitIndex < digits.length(); digitIndex++) { + for (int curSize = queue.size(); curSize > 0; curSize--) { + String str = queue.poll(); + String letter = map.get(digits.charAt(digitIndex)); + for (int letterIndex = 0; letterIndex < letter.length(); letterIndex++) { + queue.add(str + letter.charAt(letterIndex)); + } + } + } + return new ArrayList<>(queue); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0019.java b/leetcode_Java/Solution0019.java new file mode 100644 index 0000000..6b6537d --- /dev/null +++ b/leetcode_Java/Solution0019.java @@ -0,0 +1,125 @@ +// 19. 删除链表的倒数第 N 个结点 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +快慢指针:快指针先走n步,然后快慢指针同时走,直到快指针走完链表,此时慢指针所指节点的下一节点是待删除节点,修改慢指针所指节点的下一节点指针指向为下下节点 + */ +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode root = new ListNode(0, head); + ListNode slow = root; + ListNode fast = head; + for (int i = 0; i < n; i++) { + fast = fast.next; + } + while (fast != null) { + fast = fast.next; + slow = slow.next; + } + slow.next = slow.next.next; + return root.next; + } +} + + +/* +栈:后进先出,全部入栈后弹出n个节点,第n个为待删除节点,此时栈顶节点为前驱节点,修改前驱节点的下一节点指针指向下下节点 + */ +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + Stack stack = new Stack<>(); + ListNode root = new ListNode(0, head); + ListNode cur = root; + while (cur != null) { + stack.push(cur); + cur = cur.next; + } + while (n > 0) { + stack.pop(); + n--; + } + ListNode node = stack.peek(); + node.next = node.next.next; + return root.next; + } +} + + +/* +计数:遍历链表记录链表长度,计算待删除节点正数位置,再从头遍历到待删除节点的前驱节点位置,修改前驱节点的下一节点指针指向下下节点 + */ +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode root = new ListNode(0, head); + ListNode cur = root; + int len = 0; + while (head != null) { + len++; + head = head.next; + } + for (int i = 0; i < len - n; i++) { + cur = cur.next; + } + cur.next = cur.next.next; + return root.next; + } +} + + +/* +递归:累加计数 +1、方法功能:传入节点,返回该节点的倒数位置个数。如果是目标删除位置,则修改链表指针指向下下个节点 +2、终止条件:节点为空时,返回位置0 +3、递归逻辑: + 1)调用递归方法,直接走到链表尾部,逐层累加计数返回 + 2)接收递归返回值,判断该值是否为目标删除位置,是则说明下一节点是待删除节点,修改链表指针指向下下个节点 + */ +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + return rec(head, n) == n ? head.next : head; + } + + private int rec(ListNode head, int n) { + if (head == null) { + return 0; + } + int num = rec(head.next, n); + if (num == n) { + head.next = head.next.next; + } + return ++num; + } +} + + +/* +递归:递减计数 + */ +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + return track(head, n) == 0 ? head.next : head; + } + + private int track(ListNode head, int num) { + if (head == null) { + return num; + } + num = track(head.next, num); + if (num == 0) { + head.next = head.next.next; + } + return --num; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0020.java b/leetcode_Java/Solution0020.java new file mode 100644 index 0000000..0684e41 --- /dev/null +++ b/leetcode_Java/Solution0020.java @@ -0,0 +1,52 @@ +// 20. 有效的括号 + + +/* +思路: +1、括号有序,即使多层嵌套也必然至少有一对相邻有序出现,从内部逐层抵消 +2、使用while循环判断字符串的相邻有序对 + */ +class Solution { + public boolean isValid(String s) { + while (s.contains("()") || s.contains("{}") || s.contains("[]")) { + if (s.contains("()")) { + s = s.replace("()", ""); + } + if (s.contains("{}")) { + s = s.replace("{}", ""); + } + if ( s.contains("[]")) { + s = s.replace("[]", ""); + } + } + return s.isEmpty(); + } +} + + +/* +思路: +1、使用HashMap存放括号对,方便映射获取 +2、由括号的顺序特点,使用栈存放左括号,以后进先出的方式与右括号抵消 +3、字符串使用for循环遍历处理每个字符,维护一个栈,碰到左括号就入栈,碰到右括号则取出栈顶元素,判断栈顶元素和右括号是否匹配 +4、栈为空或括号不匹配,则为false,否则true + */ +class Solution { + public boolean isValid(String s) { + HashMap map = new HashMap() {{ + put('(', ')'); + put('{', '}'); + put('[', ']'); + }}; + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (map.containsKey(c)) { + stack.push(c); + } else if (stack.isEmpty() || map.get(stack.pop()) != c) { + return false; + } + } + return stack.isEmpty(); + } +} diff --git a/leetcode_Java/Solution0021.java b/leetcode_Java/Solution0021.java new file mode 100644 index 0000000..7f29a74 --- /dev/null +++ b/leetcode_Java/Solution0021.java @@ -0,0 +1,63 @@ +// 21. 合并两个有序链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +递归思路: +1、终止条件:其中一个节点为空 +2、方法功能:入参两个节点,比较值的大小,返回值较小的节点 +3、递归逻辑:下一个有序节点同样可以通过调用这个方法得到,一次递归获得值较小的节点,返回给上一层拼接成链表,最后得到有序的链表 + */ +class Solution { + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + if (list1 == null) { + return list2; + } else if (list2 == null) { + return list1; + } else if (list1.val < list2.val) { + list1.next = mergeTwoLists(list1.next, list2); + return list1; + } else { + list2.next = mergeTwoLists(list1, list2.next); + return list2; + } + } +} + + +/* +迭代思路: +1、创建一个新结点,用于最后返回链表头 +2、使用pre指针,连接结点成链表 +3、使用while循环判断并连接两个链表值较小的节点,链表的节点被连接后,该链表指针指向下一个节点继续判断 +4、其中一个链表为空后循环结束,连接另一个不为空的链表的剩余部分 + */ +class Solution { + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + ListNode head = new ListNode(-1); + ListNode pre = head; + while (list1 != null && list2 != null) { + if (list1.val < list2.val) { + pre.next = list1; + list1 = list1.next; + } else { + pre.next = list2; + list2 = list2.next; + } + pre = pre.next; + } + pre.next = list1 == null ? list2 : list1; + return head.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0022.java b/leetcode_Java/Solution0022.java new file mode 100644 index 0000000..3fbacb8 --- /dev/null +++ b/leetcode_Java/Solution0022.java @@ -0,0 +1,78 @@ +// 22. 括号生成 + + +/* +回溯: +1、画图,满二叉树,每个节点的 左子节点是(,右子节点是) +1、剪枝:左括号大于n,右括号大于左括号,这两种情况是非有效括号 +2、终止条件:字符串长度为2n,表示到达了叶子结点,满足条件,收集结果 +3、递归:每次加一个左括号或加一个右括号,然后进入下一层,并记录左括号或右括号的数量 + */ +class Solution { + private List res = new ArrayList<>(); + + public List generateParenthesis(int n) { + dfs("", n, 0, 0); + return res; + } + + private void dfs(String track, int n, int left, int right) { + if (left > n || right > left) { + return; + } + if (track.length() == 2 * n) { + res.add(track); + return; + } + dfs(track + "(", n, left + 1, right); + dfs(track + ")", n, left, right + 1); + } +} + + +/* +动态规划: +1、在求N个括号的排列组合时,把第N种情况(也就是N个括号排列组合)视为单独拿一个括号E出来,剩下的N-1个括号分为两部分, + P个括号和Q个括号,P+Q=N-1,然后这两部分分别处于括号E内和括号E的右边,各自进行括号的排列组合。 + 由于我们是一步步计算得到N个括号的情况的,所以小于等于N-1个括号的排列组合方式我们是已知的 + (用合适的数据结构存储,方便后续调用,且在存储时可利用特定数据结构实现题目某些要求,如排序,去重等), + 且P+Q=N-1,P和Q是小于等于N-1的,所以我们能直接得到P个和Q个括号的情况,进而得到N个括号的结果! +2、题目:数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。 +3、题目简化:求n对括号的所有有效组合 +4、定义dp列表:dp[i]表示i对括号的所有有效组合。本题不能用一维或二维数组,而是用二维列表,存放的是字符串对象 +5、初始化: + 1)一维dp数组扩容:增加0对括号这一最小规模的情况 + 2)dp[0]=[""], dp[1]=["()"] +6、状态转移方程:dp[i] = "(" + dp[p]的组合 + ")" + dp[q]的组合,其中1+p+q=i,p从0遍历到i-1,q则相应从i-1到0 +7、遍历dp数组填表:从前向后,第一个for循环用于遍历dp列表未知位置,第二个for循环用于遍历dp列表已知位置,得到已知结果后根据状态转移方程推断计算未知结果并填表 +8、返回结果:最后一个状态就是结果 + */ +class Solution { + public List generateParenthesis(int n) { + if (n == 0) { + return new LinkedList<>(); + } + LinkedList> dp = new LinkedList<>(); + LinkedList list1 = new LinkedList<>(); + list1.add(""); + dp.add(list1); + LinkedList list2 = new LinkedList<>(); + list2.add("()"); + dp.add(list2); + for (int i = 2; i <= n; i++) { + LinkedList temp = new LinkedList<>(); + for (int j = 0; j < i; j++) { + List l1 = dp.get(j); + List l2 = dp.get(i - 1 - j); + for (String s1 : l1) { + for (String s2 : l2) { + String s = "(" + s1 + ")" + s2; + temp.add(s); + } + } + } + dp.add(temp); + } + return dp.get(n); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0023.java b/leetcode_Java/Solution0023.java new file mode 100644 index 0000000..05d9c0f --- /dev/null +++ b/leetcode_Java/Solution0023.java @@ -0,0 +1,87 @@ +// 23. 合并K个升序链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +顺序合并:遍历链表数组,逐个链表进行合并 + */ +class Solution { + public ListNode mergeKLists(ListNode[] lists) { + ListNode root = null; + for (ListNode head : lists) { + root = mergeTwoLists(root, head); + } + return root; + } + + // 21.合并两个有序链表 + private ListNode mergeTwoLists(ListNode list1, ListNode list2) { + ListNode head = new ListNode(-1); + ListNode pre = head; + while (list1 != null && list2 != null) { + if (list1.val < list2.val) { + pre.next = list1; + list1 = list1.next; + } else { + pre.next = list2; + list2 = list2.next; + } + pre = pre.next; + } + pre.next = list1 == null ? list2 : list1; + return head.next; + } +} + + +/* +分治合并: +1、终止条件:左右边界相同则返回对应链表,左边界大于右边界则返回空 +2、方法功能:入参链表数组、左边界、右边界,将链表数组拆分成两个链表,合并链表返回 +3、递归逻辑:数组拆分后,左右两部分数组仍然需要继续拆分,直到获得两个链表进行合并,因此调用同个方法进行处理,合并后的链表返回给上一层继续合并 + */ +class Solution { + public ListNode mergeKLists(ListNode[] lists) { + return merge(lists, 0, lists.length - 1); + } + + private ListNode merge(ListNode[] lists, int left, int right) { + if (left == right) { + return lists[left]; + } + if (left > right) { + return null; + } + int mid = (left + right) / 2; + return mergeTwoLists(merge(lists, left, mid), merge(lists, mid + 1, right)); + } + + // 21.合并两个有序链表 + private ListNode mergeTwoLists(ListNode list1, ListNode list2) { + ListNode head = new ListNode(-1); + ListNode pre = head; + while (list1 != null && list2 != null) { + if (list1.val < list2.val) { + pre.next = list1; + list1 = list1.next; + } else { + pre.next = list2; + list2 = list2.next; + } + pre = pre.next; + } + pre.next = list1 == null ? list2 : list1; + return head.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0024.java b/leetcode_Java/Solution0024.java new file mode 100644 index 0000000..43d8924 --- /dev/null +++ b/leetcode_Java/Solution0024.java @@ -0,0 +1,94 @@ +// 24. 两两交换链表中的节点 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +递归: +1、方法功能:入参是一个节点,修改当前节点和下一节点指针方向,交换两个节点,返回新的头节点 +2、终止条件:head或head.next为空则直接返回头节点,因为交换至少需要两个节点 +3、返回结果:交换完成后新的头节点 +4、递归逻辑: + 1)两个节点交换完成后,新的尾节点连接着后续链表的头节点,而后续链表的头节点需要同样的交换操作,因此调用同样的方法递归处理 + 2)0个、1个节点的情况在终止条件中包含,单层递归时可以把链表当成只有2个或3个节点的简单情况,前两个节点交换完成后,连接着第三个节点newHead.next, + newHead.next作为新的头节点,同样需要交换,因此调用同样的方法 + + 1 2 3 4 + ↑ ↑ + head newHead + */ +class Solution { + public ListNode swapPairs(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode newHead = head.next; + head.next = swapPairs(newHead.next); + newHead.next = head; + return newHead; + } +} + + +/* +递归: +思路同上。上一解法第三个节点用newHead.next获取,所以要先连接好第三个节点后,newHead.next指针才能移动。 +本解法第三个节点直接用一个新的指针temp标记,所以可以先移动newHead.next指针,不会丢失第三个节点的引用。 + + 1 2 3 4 + ↑ ↑ ↑ + head newHead temp + */ +class Solution { + public ListNode swapPairs(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode temp = head.next.next; + ListNode newHead = head.next; + newHead.next = head; + head.next = swapPairs(temp); + return newHead; + } +} + + +/* +迭代: +1、多指针标记用到的节点 +2、修改节点指针方向 +3、重新初始化指针,标记下一次交换的节点 + + 0 1 2 3 4 + ↑ ↑ ↑ +root/pre start end +============================ + 0 2 1 3 4 + ↑ ↑ ↑ ↑ +root pre start end + */ +class Solution { + public ListNode swapPairs(ListNode head) { + ListNode root = new ListNode(0, head); + ListNode pre = root; + while (pre.next != null && pre.next.next != null) { + ListNode start = pre.next; + ListNode end = pre.next.next; + pre.next = end; + start.next = end.next; + end.next = start; + pre = start; + } + return root.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0025.java b/leetcode_Java/Solution0025.java new file mode 100644 index 0000000..1265d7c --- /dev/null +++ b/leetcode_Java/Solution0025.java @@ -0,0 +1,79 @@ +// 25. K 个一组翻转链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +“92.反转链表II”是只反转一次,逻辑相似 +1、指针含义 + 1)root:哨兵节点 + 2)pre:上一组链表的尾节点 + 3)start:当前组链表的头节点 + 4)end:当前组链表的尾节点 + 5)next:下一组链表的头节点 +2、当有下一组时,遍历k次找到新的当前组的尾节点end,如果不足k个节点则结束 +3、标记下一组的头节点next,用于后续与上一组连接 +4、标记当前组的头节点start,尾节点下一指针指向空,使得当前组链表独立 +5、当前组链表反转,返回新的头节点,上一组链表的尾节点pre连接当前组新的头节点end,新的尾节点start连接下一组的头节点next +6、重新初始化指针指向,pre、end指向start,准备下一轮处理 + + 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 +root/pre/end +============================================================= + 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 +root/pre end +============================================================= + 0 → 1 → 2 → 3 4 → 5 → 6 → 7 → 8 +root/pre start end next +============================================================= + 0 → 3 → 2 → 1 → 4 → 5 → 6 → 7 → 8 +root/pre end start next +============================================================= + 0 → 3 → 2 → 1 → 4 → 5 → 6 → 7 → 8 +root pre/end/start next + */ +class Solution { + public ListNode reverseKGroup(ListNode head, int k) { + ListNode root = new ListNode(0, head); + ListNode pre = root; + ListNode end = root; + while (end.next != null) { + for (int i = 0; i < k && end != null; i++) { + end = end.next; + } + if (end == null) { + break; + } + ListNode next = end.next; + ListNode start = pre.next; + end.next = null; + pre.next = reverse(start); + start.next = next; + pre = start; + end = start; + } + return root.next; + } + + // 206.反转链表 + private ListNode reverse(ListNode head) { + ListNode before = null, after; + while (head != null) { + after = head.next; + head.next = before; + before = head; + head = after; + } + return before; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0029.java b/leetcode_Java/Solution0029.java new file mode 100644 index 0000000..1f171d5 --- /dev/null +++ b/leetcode_Java/Solution0029.java @@ -0,0 +1,54 @@ +// 29. 两数相除 + + +/* +二分查找: +1、题目限定了不能使用乘法、除法和 mod 运算符 +2、通过位运算实现一个「倍增乘法」 +3、对于x除以y,结果 x/y 必然落在范围 [0,x] 内,对该范围进行二分查找 +4、数字太大时计算可能溢出,所以全部用long类型,最终结果再转成int类型 +5、处理标记结果正负号,运算过程用正数,最后再添加正负号 +6、计算中点位置时 (left + rigth + 1) / 2 的原因,假设最终剩下两个数 + 1)(left + rigth + 1) / 2 会使中点位于右边的数,当右边的数乘积大于被除数时,会收缩右边界,最后只剩下左边的数,左边的数刚好是商取整的值 + 2)(left + rigth) / 2 会使中点位于左边的数,当左边的数乘积小于被除数时,会收缩左边界,但是中点和左边界在同一位置上,所以会陷入死循环 +7、收缩边界 + 1)中点乘积 <= 被除数时,收缩左边界,由于中点乘积是小于,中点可能是目标值,所以要包括中点,即 left = mid + 2)中点乘积 > 被除数时,收缩右边界,由于中点乘积是大于,中点不可能是目标值,所以不用包括中点,即 rigth = mid - 1 + */ +class Solution { + public int divide(int dividend, int divisor) { + long x = dividend, y = divisor; + boolean isNeg = false; + if ((x < 0 && y > 0) || (x > 0 && y < 0)) { + isNeg = true; + } + x = x < 0 ? -x : x; + y = y < 0 ? -y : y; + long left = 0, rigth = x; + while (left < rigth) { + long mid = (left + rigth + 1) / 2; + if (multiply(mid, y) <= x) { + left = mid; + } else { + rigth = mid - 1; + } + } + long res = isNeg ? -left : left; + if (res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) { + return Integer.MAX_VALUE; + } + return (int) res; + } + + private long multiply(long a, long b) { + long res = 0; + while (b > 0) { + if ((b & 1) == 1) { + res += a; + } + b >>= 1; + a += a; + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0031.java b/leetcode_Java/Solution0031.java new file mode 100644 index 0000000..77a0a30 --- /dev/null +++ b/leetcode_Java/Solution0031.java @@ -0,0 +1,47 @@ +// 31. 下一个排列 + + +/* +1、“下一个排列”定义: + 1)给定数字序列的字典序中下一个更大的排列。可以理解成这些数字拼凑成的多个整数,升序排序,然后求当前整数的下一个整数 + 2)如果不存在下一个更大的排列,则将数字重新排列成最小的排列。即整数是最大的,那么整体升序排列得到一个最小的整数 +2、算法推导 + 1)我们希望下一个数比当前数大,这样才满足“下一个排列”的定义。因此只需要将后面的「大数」与前面的「小数」交换,就能得到一个更大的数 + 2)我们还希望下一个数增加的幅度尽可能的小,这样才满足“下一个排列与当前排列紧邻“的要求。为了满足这个要求,需要: + ① 在尽可能靠右的低位进行交换,需要从后向前查找 + ② 将一个尽可能小的「大数」与前面的「小数」交换 + ③ 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列 +3、算法过程 + 1)从后向前查找第一个相邻升序的元素对 (i-1,i),满足 A[i-1] < A[i],即找到第一个可交换的最低位「小数」。此时 [i,end) 必然是降序 + 2)在 [i,end) 从后向前查找第一个满足 A[i-1] < A[j] 的 j,即找到第一个可交换的值最小的「大数」。A[i-1]、A[j] 分别是「小数」、「大数」 + 3)将 A[i-1] 与 A[j] 交换 + 4)此时 [i,end) 必然是降序,逆置 [i,end),使其升序 + 5)如果在步骤1找不到符合的相邻升序元素对,说明当前 [0,end) 为一个降序顺序,即最大的排序,则整体升序得到最小的排列 + +1 2 3 8 5 7 6 4 + ↑ ↑ ↑ + i-1 i j +1 2 3 8 6 4 5 7 + */ +class Solution { + public void nextPermutation(int[] nums) { + int n = nums.length; + if (n <= 1) { + return; + } + for (int i = n - 1; i >= 1; i--) { + if (nums[i] > nums[i - 1]) { + for (int j = n - 1; j >= i; j--) { + if (nums[j] > nums[i - 1]) { + int temp = nums[j]; + nums[j] = nums[i - 1]; + nums[i - 1] = temp; + Arrays.sort(nums, i, n); + return; + } + } + } + } + Arrays.sort(nums); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0032.java b/leetcode_Java/Solution0032.java new file mode 100644 index 0000000..c0f0af8 --- /dev/null +++ b/leetcode_Java/Solution0032.java @@ -0,0 +1,114 @@ +// 32. 最长有效括号 + + +/* +栈: +1、通过栈,可以在遍历字符串的过程中去判断到目前为止扫描的子串的有效性,同时能得到最长有效括号的长度 +2、始终保持栈底元素为当前已经遍历过的元素中「最后一个没有被匹配的右括号的下标」,这样的做法主要是考虑了边界条件的处理,栈里其他元素维护左括号的下标 +3、先初始化栈,往栈中放入一个值为 −1 的元素,表示「最后一个没有被匹配的右括号的下标」 +4、遇到'('时将它的下标入栈 +5、遇到')'时,先弹出栈顶元素表示匹配了当前右括号 + 1)如果栈为空,说明当前的右括号为没有被匹配的右括号,我们将其下标放入栈中来更新「最后一个没有被匹配的右括号的下标」 + 2)如果栈不为空,当前右括号的下标减去栈顶元素即为「以该右括号为结尾的最长有效括号的长度」 + */ +class Solution { + public int longestValidParentheses(String s) { + int res = 0; + Deque stack = new ArrayDeque<>(); + stack.push(-1); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + stack.push(i); + } else { + stack.pop(); + if (stack.isEmpty()) { + stack.push(i); + } else { + res = Math.max(res, i - stack.peek()); + } + } + } + return res; + } +} + + +/* +贪心,计数: +1、正向遍历,统计左括号和右括号的数量 + 当数量相等时说明凑成了有效括号,此时计算子串长度并更新最长长度 + 当右括号数量大于左括号数量时,那么前面遍历过的括号将无法再凑成有效括号,因此前面作废,计数归零,重新开始计算有效括号长度 +2、反向遍历同上,当左括号数量大于右括号数量时重新计算 +3、双向遍历的原因 + 1)s = "())" 正向遍历才有左右括号数量相等的时候 + 2)s = "(()" 反向遍历才有左右括号数量相等的时候 + */ +class Solution { + public int longestValidParentheses(String s) { + int n = s.length(); + int res = 0, left = 0, right = 0, reverseLeft = 0, reverseRight = 0; + for (int i = 0; i < n; i++) { + if (s.charAt(i) == '(') { + left++; + } else { + right++; + } + if (left == right) { + res = Math.max(res, 2 * left); + } else if (right > left) { + left = right = 0; + } + + if (s.charAt(n - 1 - i) == '(') { + reverseLeft++; + } else { + reverseRight++; + } + if (reverseLeft == reverseRight) { + res = Math.max(res, 2 * reverseLeft); + } else if (reverseLeft > reverseRight) { + reverseLeft = reverseRight = 0; + } + } + return res; + } +} + + +/* +动态规划: +1、定义dp数组:dp[i]表示 以索引i的字符结尾的子串 形成的最长有效括号的长度 +2、初始化:默认为0,不用初始化 +3、状态转移方程: + 1)跳过前一字符结尾的最长有效括号的范围,找到与当前括号匹配的左括号的位置,如果该位置有效且确实是左括号, + 那么产生了一对有效括号,数量为 前一字符结尾的最长有效括号长度 加2,即 dp[i] = dp[i - 1] + 2 + 2)在当前字符为有效括号的基础上,再把 当前字符结尾的有效括号范围 前面的有效括号长度 加上,得到 当前字符结尾的最长有效括号的长度 +4、遍历dp数组填表:从索引1开始遍历,因为dp[0]只有一个字符构不成有效括号,当遇到右括号时开始计算填表 +5、返回结果:最大的状态就是结果 + + ( ) ( ( ) ( ) ) + ↑ ↑ ↑ + pre-1 pre i + */ +class Solution { + public int longestValidParentheses(String s) { + int n = s.length(); + if (n < 2) { + return 0; + } + int[] dp = new int[n]; + for (int i = 1; i < n; i++) { + if (s.charAt(i) == ')') { + int preLen = dp[i - 1]; + int pre = i - 1 - preLen; + if (pre >= 0 && s.charAt(pre) == '(') { + dp[i] = dp[i - 1] + 2; + if (pre - 1 >= 0) { + dp[i] += dp[pre - 1]; + } + } + } + } + return Arrays.stream(dp).max().getAsInt(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0033.java b/leetcode_Java/Solution0033.java new file mode 100644 index 0000000..27c3ccf --- /dev/null +++ b/leetcode_Java/Solution0033.java @@ -0,0 +1,59 @@ +// 33. 搜索旋转排序数组 + + +/* +直接遍历查找,时间复杂度O(n) + */ +class Solution { + public int search(int[] nums, int target) { + for (int i = 0; i < nums.length; i++) { + if (nums[i] == target) { + return i; + } + } + return -1; + } +} + + +/* +简单题“704.二分查找” +二分查找:时间复杂度O(logn) +1、左右索引求和除以2,得到中点索引,如果中点索引对应值为目标值,则返回中点索引 +2、在常规二分查找的时候查看当前 mid 为分割位置分割出来的两个部分 [l, mid-1] 和 [mid+1, r] 哪个部分是有序的,并判断 target 是否在有序的部分,从而决定改变二分查找的上下界 + 如果 nums[left] < nums[mid],那么左半部分 [l, mid-1] 是有序数组。如果 target 的大小满足 nums[left] <= target < nums[mid] ,则到 [l, mid-1]寻找,否则在 [mid+1, r] 寻找 + 如果 nums[left] > nums[mid],那么右半部分 [mid+1, r] 是有序数组。如果 target 的大小满足 nums[mid] < target <= nums[right],则到 [mid+1, r]寻找,否则在 [l, mid-1] 寻找 + */ +class Solution { + public int search(int[] nums, int target) { + int n = nums.length; + if (n == 0) { + return -1; + } + if (n == 1) { + return nums[0] == target ? 0 : -1; + } + int left = 0, right = n - 1; + while (left <= right) { // 可能最后只剩下一个数要判断,所以需要等号 + int mid = (left + right) / 2; // (left + right + 1) / 2 也可以,因为中值判断过不满足就舍弃,所以不会存在重复中点死循环问题 + if (nums[mid] == target) { // 判断中点是否为目标值,是则返回中点 + return mid; + } + // 当剩下两个数时,中点落在左边,由于上面已经校验过中值不等于目标值,所以当前数要舍弃,期望左指针右移,所以需要等号,使if条件成立进入里面的逻辑,让左指针右移 + if (nums[left] <= nums[mid]) { // 左半部分有序 + if (nums[left] <= target && target < nums[mid]) { // 目标值在左半部分。[left,mid) 因为左值还没判断,中值已经判断过了 + right = mid - 1; // 收缩右区间,中值已经判断过不满足了,不需要包含 + } else { // 目标值在右半部分 + left = mid + 1; // 收缩左区间,中值已经判断过不满足了,不需要包含 + } + } else { // 右半部分有序 + if (nums[mid] < target && target <= nums[right]) { // 目标值在右半部分。(mid,right] 因为右值还没判断,中值已经判断过了 + left = mid + 1; // 收缩左区间,中值已经判断过不满足了,不需要包含 + } else { // 目标值在左半部分 + right = mid - 1; // 收缩右区间,中值已经判断过不满足了,不需要包含 + } + } + } + return -1; // 找不到返回-1 + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0034.java b/leetcode_Java/Solution0034.java new file mode 100644 index 0000000..8e74176 --- /dev/null +++ b/leetcode_Java/Solution0034.java @@ -0,0 +1,40 @@ +// 34. 在排序数组中查找元素的第一个和最后一个位置 + + +/* +二分查找: +1、二分查找,找到中点位置的值,比较判断是否为目标值 +2、若不是目标值,则缩小一半的查找区间 +3、若是目标值,则向两边扩散查找左右边界 + */ +class Solution { + public int[] searchRange(int[] nums, int target) { + int n = nums.length; + int left = 0, right = n - 1; + int[] res = new int[2]; + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] == target) { + for (int i = mid; i >= 0; i--) { + if (nums[i] != target) { + break; + } + res[0] = i; + } + for (int i = mid; i < n; i++) { + if (nums[i] != target) { + break; + } + res[1] = i; + } + return res; + } else if (nums[mid] < target) { + left = mid + 1; + } else { + right = mid - 1; + } + } + Arrays.fill(res, -1); + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0037.java b/leetcode_Java/Solution0037.java new file mode 100644 index 0000000..67121a9 --- /dev/null +++ b/leetcode_Java/Solution0037.java @@ -0,0 +1,67 @@ +// 37. 解数独 + + +/* +回溯: +1、本题中棋盘的每一个位置都要放一个数字,并检查数字是否合法,解数独的树形结构要比N皇后更宽更深。 +2、为什么递归函数的返回值需要是bool类型? + 因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值 +3、本题在原二维数组上操作,因此不需要增加额外的数据结构 +4、本题递归不用终止条件,解数独是要遍历整个树形结构寻找可能的叶子节点就立刻返回 +5、本题需要 二维递归,也就是两个for循环嵌套着递归 + 一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性! + */ +class Solution { + public void solveSudoku(char[][] board) { + backtrack(board); + } + + private boolean backtrack(char[][] board) { + for (int row = 0; row < 9; row++) { + for (int col = 0; col < 9; col++) { + if (board[row][col] != '.') { + continue; + } + for (char val = '1'; val <= '9'; val++) { + if (isValid(row, col, val, board)) { + board[row][col] = val; + if (backtrack(board)) { + return true; + } + board[row][col] = '.'; + } + } + // 9个数都试完了,都不行,那么就返回false + return false; + } + } + // 遍历完没有返回false,说明找到了合适棋盘位置 + return true; + } + + private boolean isValid(int row, int col, char val, char[][] board) { + // 判断同一行是否有重复的数 + for (int i = 0; i < 9; i++) { + if (board[row][i] == val) { + return false; + } + } + // 判断同一列是否有重复的数 + for (int j = 0; j < 9; j++) { + if (board[j][col] == val) { + return false; + } + } + // 判断九宫格是否有重复的数 + int startRow = (row / 3) * 3; + int startCol = (col / 3) * 3; + for (int i = startRow; i < startRow + 3; i++) { + for (int j = startCol; j < startCol + 3; j++) { + if (board[i][j] == val) { + return false; + } + } + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0039.java b/leetcode_Java/Solution0039.java new file mode 100644 index 0000000..f3b206e --- /dev/null +++ b/leetcode_Java/Solution0039.java @@ -0,0 +1,38 @@ +// 39. 组合总和 + + +/* +回溯: +1、定义全局变量res存放回溯过程得到的所有子结果 +2、定义全局变量track存放回溯过程的临时子结果 +3、调用递归函数,处理得到所有子结果,返回结果 +4、定义递归函数 + 1)终止条件,总和等于目标值,存储子结果 + 2)剪枝条件,总和大于目标值,结束 + 3)for循环遍历数组,做选择 → 递归 → 撤销选择,回溯 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> combinationSum(int[] candidates, int target) { + backtrack(candidates, 0, target); + return res; + } + + private void backtrack(int[] candidates, int index, int target) { + int sum = track.stream().mapToInt(x -> x).sum(); + if (sum == target) { + res.add(new ArrayList<>(track)); + return; + } + if (sum > target) { + return; + } + for (int i = index; i < candidates.length; i++) { + track.addLast(candidates[i]); + backtrack(candidates, i, target); + track.removeLast(); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0040.java b/leetcode_Java/Solution0040.java new file mode 100644 index 0000000..69da785 --- /dev/null +++ b/leetcode_Java/Solution0040.java @@ -0,0 +1,38 @@ +// 40. 组合总和 II + + +/* +回溯: +1、思路与'39.组合总和'相同 +2、不同点:有重复元素,解集不能包含重复的组合,因此要过滤重复的选择 +3、增加剪枝条件:先数组排序,同一层元素做选择时,如果该元素前面出现过,则跳过,因为前面的选择已经包含当前情况了 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> combinationSum2(int[] candidates, int target) { + Arrays.sort(candidates); + backtrack(candidates, 0, target); + return res; + } + + private void backtrack(int[] candidates, int startIndex, int target) { + int sum = track.stream().mapToInt(x -> x).sum(); + if (sum == target) { + res.add(new ArrayList<>(track)); + return; + } + if (sum > target) { + return; + } + for (int i = startIndex; i < candidates.length; i++) { + if (i > startIndex && candidates[i] == candidates[i - 1]) { + continue; + } + track.addLast(candidates[i]); + backtrack(candidates, i + 1, target); + track.removeLast(); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0041.java b/leetcode_Java/Solution0041.java new file mode 100644 index 0000000..dfe5883 --- /dev/null +++ b/leetcode_Java/Solution0041.java @@ -0,0 +1,79 @@ +// 41. 缺失的第一个正数 + + +/* +置换: +1、求缺失的第一个正数,所以要找的数一定在[1,n+1] +2、遍历数组,在i位置上,将i位置的元素x交换到x-1的位置上,即元素值与索引对应。循环交换i位置的元素,直到不满足条件 +3、遍历数组,如果i位置上的元素值不是i+1,说明缺失的第一个正数是i+1 +4、数组元素和索引都对应了,则缺失的第一个正数是n+1 + */ +class Solution { + public int firstMissingPositive(int[] nums) { + int n = nums.length; + for (int i = 0; i < n; i++) { + while (nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { + int temp = nums[nums[i] - 1]; + nums[nums[i] - 1] = nums[i]; + nums[i] = temp; + } + } + for (int i = 0; i < n; i++) { + if (nums[i] != i + 1) { + return i + 1; + } + } + return n + 1; + } +} + + +/* +排序: +1、数组升序排序 +2、遍历数组,索引走到对应值为正数位置 +3、索引走完即没有正数,或者第一个正数不是1,那么直接返回缺失的第一个正数为1 +4、遍历上一步索引开始的剩余数组,如果下一个数不是 相等或连续,说明缺失正数,返回缺失的正数 +5、如果遍历完没有缺失,则缺失的第一个正数是最后一个数加1 + */ +class Solution { + public int firstMissingPositive(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + int index = 0; + while (index < n && nums[index] < 1) { + index++; + } + if (index == n || nums[index] != 1) { + return 1; + } + for (int i = index; i < n - 1; i++) { + if (nums[i] != nums[i + 1] && nums[i] + 1 != nums[i + 1]) { + return nums[i] + 1; + } + } + return nums[n - 1] + 1; + } +} + + +/* +集合: +1、遍历数组将元素存入集合 +2、求缺失的第一个正数,所以要找的数一定在[1,n+1],如果该数字没有在集合中,说明该数字是缺失的第一个正数,否则缺失的第一个正数是最后一个数加1 + */ +class Solution { + public int firstMissingPositive(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + int n = nums.length; + for (int i = 1; i <= n; i++) { + if (!set.contains(i)) { + return i; + } + } + return n + 1; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0042.java b/leetcode_Java/Solution0042.java new file mode 100644 index 0000000..92462ab --- /dev/null +++ b/leetcode_Java/Solution0042.java @@ -0,0 +1,158 @@ +// 42. 接雨水 + + +/* +逐行累加雨水: +1、start标志表示是否碰到柱子,碰到则开始计算,避免左侧没有柱子时错误计算 +2、tempSum表示两根柱子中间的雨水,遍历时碰到雨水就收集,碰柱子就将柱子间的雨水加入总和,清空当前柱子间的雨水,准备计算下一处柱子间的雨水 +3、要碰到柱子才将雨水加入总和,避免左边有柱子,右边没有柱子,这种情况没有雨水 + */ +class Solution { + public int trap(int[] height) { + int max = Arrays.stream(height).max().getAsInt(); + int sum = 0; + for (int i = 1; i <= max; i++) { + boolean start = false; + int tempSum = 0; + for (int j = 0; j < height.length; j++) { + if (start && height[j] < i) { + tempSum++; + } + if (height[j] >= i) { + sum += tempSum; + tempSum = 0; + start = true; + } + } + } + return sum; + } +} + + +/* +逐列累加雨水: +1、遍历数组,首尾不用,因为首尾那一列左右柱子不足,不能接雨水 +2、遍历到某一位置时,求该位置 左边最高柱子的高度 和 右边最高柱子的高度,两个最高取较低者,较低者高于当前位置则可以接高度差的雨水,否则不能接雨水 + */ +class Solution { + public int trap(int[] height) { + int n = height.length; + int sum = 0; + for (int i = 1; i < n - 1; i++) { + int leftMax = getMax(height, 0, i - 1); + int rightMax = getMax(height, i + 1, n - 1); + int minVal = Math.min(leftMax, rightMax); + sum += (minVal > height[i]) ? minVal - height[i] : 0; + } + return sum; + } + + private int getMax(int[] height, int start, int end) { + int maxVal = 0; + for (int i = start; i <= end; i++) { + maxVal = Math.max(height[i], maxVal); + } + return maxVal; + } +} + + +/* +逐列累加雨水,动态规划,时间复杂度优化,空间换时间: +1、为避免重复遍历计算某位置的左右最高柱子,使用dp数组存放最高柱子 +2、定义dp数组:dpLeft[i]表示i位置左边最高柱子的高度,dpRight[i]表示i位置右边最高柱子的高度 +3、初始化: + 1)一维dp数组不用扩容 + 2)dp[0]=0,不用赋值了 +4、状态转移方程: + dpLeft[i] = Math.max(dpLeft[i - 1], height[i - 1]); + dpRight[i] = Math.max(dpRight[i + 1], height[i + 1]); +4、遍历dp数组填表:一个for循环遍历dp数组填表,求 左边最高柱子的高度 则 从左往右 遍历,求 右边最高柱子的高度 则 从右往左 遍历 + */ +class Solution { + public int trap(int[] height) { + int n = height.length; + int sum = 0; + int[] dpLeft = new int[n]; + int[] dpRight = new int[n]; + for (int i = 1; i < n - 1; i++) { + dpLeft[i] = Math.max(dpLeft[i - 1], height[i - 1]); + } + for (int i = n - 2; i > 0; i--) { + dpRight[i] = Math.max(dpRight[i + 1], height[i + 1]); + } + for (int i = 1; i < n - 1; i++) { + int minVal = Math.min(dpLeft[i], dpRight[i]); + sum += (minVal > height[i]) ? minVal - height[i] : 0; + } + return sum; + } +} + + +/* +双指针: +1、变量含义 + leftMax:左边的最大值,它是从左往右遍历找到的 + rightMax:右边的最大值,它是从右往左遍历找到的 + left:从左往右处理的当前下标 + right:从右往左处理的当前下标 +2、双指针left、right的作用是 从两端向中间遍历整个数组,记录左右最大值,并计算每个位置的雨水 +3、在某个位置i处,它能存的水,取决于它左右两边的最大值中较小的一个,与当前位置的高度差 +4、在某个位置i处,它左边最大值一定是leftMax,右边最大值大于等于rightMax + 所以如果 leftMax <= rightMax,那么 左边最大值 <= 右边最大值,那么位置i的 左右最大值 较小者就是 leftMax + 所以当 leftMax <= rightMax 时,就去处理left下标,反之就去处理right下标 + */ +class Solution { + public int trap(int[] height) { + int left = 0, right = height.length - 1; + int leftMax = 0, rightMax = 0; + int sum = 0; + while (left <= right) { + if (leftMax <= rightMax) { + sum += Math.max(0, leftMax - height[left]); + leftMax = Math.max(leftMax, height[left]); + left++; + } else { + sum += Math.max(0, rightMax - height[right]); + rightMax = Math.max(rightMax, height[right]); + right--; + } + } + return sum; + } +} + + +/* +单调递减栈: +1、单调递减栈,height元素作为右柱依次入栈,出现入栈元素(右柱)比栈顶大时,说明在右柱左侧形成了低洼处 +2、栈不为空,且当前元素(右柱)比栈顶(右柱的左侧)大,说明形成低洼处了 +3、低洼处出栈后,栈如果为空,说明没有左柱,不能接雨水 +4、否则,获取低洼处、左柱、右柱的高度,计算雨水。 + 积攒的水 = 距离 * 高度差 + = (右柱位置-左柱位置-1) * (min(右柱高度, 左柱高度)-低洼处高度) +5、循环结算完雨水后,右柱入栈,保证了栈内元素单调递减 + */ +class Solution { + public int trap(int[] height) { + int sum = 0; + Stack stack = new Stack<>(); + for (int right = 0; right < height.length; right++) { + while (!stack.empty() && height[right] > height[stack.peek()]) { + int bottom = stack.pop(); + if (stack.empty()) { + break; + } + int left = stack.peek(); + int bottomHeight = height[bottom]; + int leftHeight = height[left]; + int rightHeight = height[right]; + sum += (right - left - 1) * (Math.min(leftHeight, rightHeight) - bottomHeight); + } + stack.push(right); + } + return sum; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0043.java b/leetcode_Java/Solution0043.java new file mode 100644 index 0000000..c0ccf67 --- /dev/null +++ b/leetcode_Java/Solution0043.java @@ -0,0 +1,110 @@ +// 43. 字符串相乘 + + +/* +模拟相乘:遍历num2每一位与num1进行相乘,将每一步的结果进行累加 +1、其中一个数为0,则乘积为0 +2、从右到左遍历num2,根据当前位数对结果补0,获取当前位置数字n1 +3、从右到左遍历num1,如果num1遍历完了但当前进位大于0则赋值数字为0,否则直接获取,最终得到当前位置数字n2 +4、两数相乘得到乘积,取个位存入结果字符串,取十位作为进位。直到计算完num2的一位与num1的所有位乘积 +5、num2每计算完一位后,就要把当前计算结果与前面的计算结果进行字符串相加,最终得到num2每一位乘积结果的和 + +num1 1 2 3 +num2 4 5 6 + --------- + 7 3 8 + 6 1 5 0 + 4 9 2 0 0 + */ +class Solution { + public String multiply(String num1, String num2) { + if (num1.equals("0") || num2.equals("0")) { + return "0"; + } + String res = "0"; + int len1 = num1.length(); + int len2 = num2.length(); + for (int i = len2 - 1; i >= 0; i--) { + int carry = 0; + StringBuilder temp = new StringBuilder(); + for (int k = 0; k < len2 - 1 - i; k++) { + temp.append("0"); + } + int n2 = num2.charAt(i) - '0'; + for (int j = len1 - 1; j >= 0 || carry > 0; j--) { + int n1 = j >= 0 ? num1.charAt(j) - '0' : 0; + int multiply = (n1 * n2 + carry); + temp.append(multiply % 10); + carry = multiply / 10; + } + res = addStrings(res, temp.reverse().toString()); + } + return res; + } + + // 415. 字符串相加 + private String addStrings(String num1, String num2) { + int i = num1.length() - 1; + int j = num2.length() - 1; + int carry = 0; + StringBuilder res = new StringBuilder(); + while (i >= 0 || j >= 0 || carry > 0) { + int x = i >= 0 ? num1.charAt(i--) - '0' : 0; + int y = j >= 0 ? num2.charAt(j--) - '0' : 0; + int sum = x + y + carry; + carry = sum / 10; + res.append(sum % 10); + } + return res.reverse().toString(); + } +} + + +/* +两数相乘位置规律: +1、乘数 num1 位数为 M,被乘数 num2 位数为 N, num1 x num2 结果 res 最大总位数为 M+N +2、num1[i] x num2[j] 的结果 multiply 位数为两位,"0x" 或 "xy" 的形式,其第一位位于 cal[i+j],第二位位于 cal[i+j+1] +3、从右到左遍历num1和num2,分别取出两个数字相乘,再加上一步乘积的十位防止被覆盖,然后将结果的个位和十位存入cal数组 +4、遍历cal数组,构造结果字符串返回 + + 1 2 3 ==> 2的索引i为1 + 4 5 ==> 4的索引j为0 + ---------- + 1 5 + 1 0 + 0 5 + ---------- + 1 2 + 0 8 ==> cal[i+1] cal[i+j+1] + 0 4 + ---------- +cal 0 1 2 3 4 + + */ +class Solution { + public String multiply(String num1, String num2) { + if (num1.equals("0") || num2.equals("0")) { + return "0"; + } + int len1 = num1.length(); + int len2 = num2.length(); + int[] cal = new int[len1 + len2]; + for (int i = len1 - 1; i >= 0; i--) { + int n1 = num1.charAt(i) - '0'; + for (int j = len2 - 1; j >= 0; j--) { + int n2 = num2.charAt(j) - '0'; + int multiply = (n1 * n2 + cal[i + j + 1]); + cal[i + j + 1] = multiply % 10; + cal[i + j] += multiply / 10; + } + } + StringBuilder res = new StringBuilder(); + for (int i = 0; i < cal.length; i++) { + if (i == 0 && cal[i] == 0) { + continue; + } + res.append(cal[i]); + } + return res.toString(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0046.java b/leetcode_Java/Solution0046.java new file mode 100644 index 0000000..42008ed --- /dev/null +++ b/leetcode_Java/Solution0046.java @@ -0,0 +1,67 @@ +// 46. 全排列 + + +/* +回溯: +1、定义全局变量res存放回溯过程得到的所有子结果 +2、定义全局变量track存放回溯过程的临时子结果 +3、调用递归函数,处理得到所有子结果,返回结果 +4、定义递归函数 + 1)终止条件,存储子结果 + 2)for循环:剪枝条件 → 做选择 → 递归 → 撤销选择,回溯 +5、由于存储子结果的变量在遍历过程中作为临时存储,当需要添加子结果时拷贝一份即可,因此可以重复使用 + */ +class Solution { + private List> res = new ArrayList<>(); + private LinkedList track = new LinkedList<>(); + + public List> permute(int[] nums) { + backtrack(nums); + return res; + } + + private void backtrack(int[] nums) { + if (track.size() == nums.length) { + res.add(new ArrayList(track)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (track.contains(nums[i])) { + continue; + } + track.addLast(nums[i]); + backtrack(nums); + track.removeLast(); + } + } +} + + + +/* +逻辑同上 + */ +class Solution { + private List> res = new ArrayList<>(); + + public List> permute(int[] nums) { + LinkedList track = new LinkedList<>(); + backtrack(nums, track); + return res; + } + + private void backtrack(int[] nums, LinkedList track) { + if (track.size() == nums.length) { + res.add(new ArrayList(track)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (track.contains(nums[i])) { + continue; + } + track.add(nums[i]); + backtrack(nums, track); + track.removeLast(); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0047.java b/leetcode_Java/Solution0047.java new file mode 100644 index 0000000..8c8d255 --- /dev/null +++ b/leetcode_Java/Solution0047.java @@ -0,0 +1,48 @@ +// 47. 全排列 II + + +/* +回溯: +1、定义全局变量res存放回溯过程得到的所有子结果,定义全局变量track存放回溯过程的临时子结果,定义全局便变量used存放数组元素使用过情况 +2、包含重复的元素,因此做选择时,树层要去重,树枝不用去重。去重必须先数组排序 +3、调用递归函数,处理得到所有子结果,返回结果 +4、定义递归函数 + 1)终止条件,子结果大小满足条件,存储子结果 + 2)for循环遍历数组:剪枝条件 → 做选择 → 递归 → 撤销选择,回溯 + ① 剪枝条件:当前元素使用过则跳过;或者当前元素未使用过,但同层前面有同样的元素使用过,则跳过重复选择 + 去重代码 i > 0 && nums[i] == nums[i - 1] && !used[i - 1] + used[i - 1] = false 表示树层去重,即前一个状态已撤销,为同层。效率更高,避免无效处理。 + used[i - 1] = true 表示树枝去重,即前一个状态未撤销,为递归,不同层。 + ② 做选择:元素只加入子结果,标记当前元素已使用 + ③ 递归:进入下一层,同样遍历整个数组,通过used标记判断元素是否有效可用 + ④ 回溯:撤销选择,移除子结果最后一个元素,标记当前元素未使用 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + private boolean[] used; + + public List> permuteUnique(int[] nums) { + used = new boolean[nums.length]; + Arrays.sort(nums); + backtrack(nums); + return res; + } + + private void backtrack(int[] nums) { + if (track.size() == nums.length) { + res.add(new ArrayList<>(track)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])) { + continue; + } + track.addLast(nums[i]); + used[i] = true; + backtrack(nums); + track.removeLast(); + used[i] = false; + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0048.java b/leetcode_Java/Solution0048.java new file mode 100644 index 0000000..3c8d744 --- /dev/null +++ b/leetcode_Java/Solution0048.java @@ -0,0 +1,94 @@ +// 48. 旋转图像 + + +/* +翻转: +1、对角线翻转:对角线元素交换 +2、水平翻转:左右两侧元素交换 + +1 2 3 1 4 7 7 4 1 +4 5 6 → 2 5 8 → 8 5 2 +7 8 9 3 6 9 9 6 3 + */ +class Solution { + public void rotate(int[][] matrix) { + int n = matrix.length; + for (int i = 0; i < n; i++) { + for (int j = 0; j < i; j++) { + int temp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = temp; + } + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < n / 2; j++) { + int temp = matrix[i][j]; + matrix[i][j] = matrix[i][n - 1 - j]; + matrix[i][n - 1 - j] = temp; + } + } + } +} + + +/* +原地旋转: +1、箭头横向是行,纵向是列 +2、确定旋转位置,定位一个点,推算出旋转后在对应四个位置上的索引,每次遍历都是交换这四个点的位置 + 1)赋值方向:(i, j) → (j, n-1-i) → (n-1-i, n-1-j) → (n-1-j, i) → (i, j) + 2)索引变化规律: + ① 当前点的列 直接变成 下一点的行 ( ,x) → (x, ) + ② 当前点的行 转化变成 下一点的列 (x, ) → ( ,n-1-x) (n-1-x, ) → ( ,x) + ③ 确定下一选择位置的索引,直接根据以上两个规律写出坐标 +3、确定遍历范围,每次遍历都是操作四个点,所以只需要遍历 n²/4 个格子即可,对n为偶数和奇数的情况将格子四等分,推算出统一的遍历范围 + 0 <= i < n/2 + 0 <= j < (n+1)/2 + + j + ↓ + i → 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 + + n-1-i + ↓ + 1 2 3 4 5 + 6 7 8 9 10 ← j + 11 12 13 14 15 + 16 17 18 19 20 + 21 22 23 24 25 + + 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 ← n-1-i + ↑ + n-1-j + + 1 2 3 4 5 + 6 7 8 9 10 + 11 12 13 14 15 +n-1-j → 16 17 18 19 20 + 21 22 23 24 25 + ↑ + i + + */ +class Solution { + public void rotate(int[][] matrix) { + int n = matrix.length; + int row = n / 2, col = (n + 1) / 2; + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + int temp = matrix[i][j]; + matrix[i][j] = matrix[n - 1 - j][i]; + matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j]; + matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i]; + matrix[j][n - 1 - i] = temp; + } + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0051.java b/leetcode_Java/Solution0051.java new file mode 100644 index 0000000..8caa891 --- /dev/null +++ b/leetcode_Java/Solution0051.java @@ -0,0 +1,129 @@ +// 51. N 皇后 + + +/* +回溯 + +思路: +1、皇后有效位置:不能同行、不能同列、不能同斜线 +2、检查皇后位置是否有效,即检查同列、45°角、135°角是否有皇后。当前行只有一个皇后,不用检查;下半部分的行未遍历,不用检查 +3、棋盘的宽度就是for循环的长度,棋盘的高度就是递归的深度 + +步骤: +1、定义全局结果列表res,定义二维字符数组chessBoard表示棋盘 +2、初始化棋盘,调用递归函数,处理得到结果,返回结果 +3、定义递归函数 + 1)终止条件:棋盘的行遍历完,将 二维字符数组 转 字符串列表,存入res + 2)单层递归逻辑:遍历该行的每一列,选择一个位置,判断能否放皇后,能则进入下一行递归处理,回溯撤销皇后,继续判断下一列 + */ +class Solution { + private List> res = new ArrayList<>(); + private char[][] chessBoard; + private int n; + + public List> solveNQueens(int n) { + this.n = n; + this.chessBoard = new char[n][n]; + for (char[] c : chessBoard) { + Arrays.fill(c, '.'); + } + backtrack(0); + return res; + } + + private void backtrack(int row) { + if (row == n) { + res.add(arrayToList()); + return; + } + for (int col = 0; col < n; col++) { + if (isValid(row, col)) { + chessBoard[row][col] = 'Q'; + backtrack(row + 1); + chessBoard[row][col] = '.'; + } + } + } + + // 二维字符数组 转 字符串列表 + private List arrayToList() { + List list = new ArrayList<>(); + for (char[] c : chessBoard) { + list.add(String.copyValueOf(c)); + } + return list; + } + + // 检查是否有皇后 + private boolean isValid(int row, int col) { + // 检查列 + for (int i = 0; i < row; i++) { + if (chessBoard[i][col] == 'Q') { + return false; + } + } + // 检查45°角 + for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { + if (chessBoard[i][j] == 'Q') { + return false; + } + } + // 检查135°角 + for (int i = row - 1, j = col + 1; i >=0 && j < n; i--, j++) { + if (chessBoard[i][j] == 'Q') { + return false; + } + } + return true; + } +} + + +/* +回溯,同上,检查是否有皇后思路不同 +思路:遍历每一行。因为每一行n、每一列col、每一对角线dg、每一反对角线bdg,最多只能存在一个皇后 +其中对角线bg相当于一个跨坐标轴一三象限的y=x+b函数,反对角线bdg相当于一个跨坐标轴二四象限的y=-x+b函数 +两者截距b分别为y-x和y+x,由于y-x可能为负数,又因为数组下标不能为负数,故需要加上一个偏移量n +所以对应到两对角线的代码分别为:n - u + i和u + i + */ +class Solution { + private List> res = new ArrayList<>(); + char[][] chessBoard; + boolean col[], dg[], bdg[]; + + public List> solveNQueens(int n) { + chessBoard = new char[n][n]; + for (char[] c : chessBoard) { + Arrays.fill(c, '.'); + } + col = new boolean[2 * n]; + dg = new boolean[2 * n]; + bdg = new boolean[2 * n]; + backtrack(n, 0); + return res; + } + + private void backtrack(int n, int row) { + if (row == n) { + res.add(arrayToList()); + return; + } + for (int i = 0; i < n; i++) { + if (!col[i] && !dg[n - row + i] && !bdg[row + i]) { + chessBoard[row][i] = 'Q'; + col[i] = dg[n - row + i] = bdg[row + i] = true; + backtrack(n, row + 1); + chessBoard[row][i] = '.'; + col[i] = dg[n - row + i] = bdg[row + i] = false; + } + } + } + + private List arrayToList() { + List list = new ArrayList<>(); + for (char[] c : chessBoard) { + list.add(String.copyValueOf(c)); + } + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0053.java b/leetcode_Java/Solution0053.java new file mode 100644 index 0000000..ab55ab5 --- /dev/null +++ b/leetcode_Java/Solution0053.java @@ -0,0 +1,66 @@ +// 53. 最大子数组和 + + +/* +贪心思路: +1、遍历数组,当前元素的 之前和大于0 时,则加上当前值得到当前和,这样累加值才会更大,否则将当前值赋给当前和 +2、当前和只是一个中间变量,记录过程中每个局部最大和。比较历史最大值 和 当前和,得到较大值 + */ +class Solution { + public int maxSubArray(int[] nums) { + int res = nums[0]; + int sum = 0; + for (int num : nums) { + if (sum > 0) { + sum += num; + } else { + sum = num; + } + res = Math.max(res, sum); + } + return res; + } +} + + +/* +贪心思路: +1、核心思路都是判断以前一个元素结尾的子序列的最大值能不能给当前元素结尾的序列提供增益 +2、如果之前和为负数就不能提供增益,加上当前元素后会比当前元素小,因此通过比较大小就能获得当前和的最大值 + */ +class Solution { + public int maxSubArray(int[] nums) { + int res = nums[0]; + int sum = 0; + for (int num : nums) { + sum = Math.max(sum + num, num); + res = Math.max(res, sum); + } + return res; + } +} + + +/* +动态规划思路: +1、题目:给你一个整数数组 nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。 +2、题目简化:求数组nums的具有最大和的连续子数组的和。要先求多个局部连续子数组的最大和,再从多个局部最大中得到全局最大 +3、定义dp数组:dp[i]表示以索引i结尾的连续子数组的最大和 +4、初始化: + 1)一维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)dp[0] = nums[0]; +5、状态转移方程:dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]); +6、遍历dp数组填表:一个for循环遍历dp数组,根据状态转移方程推断计算未知结果并填表 +7、返回结果:dp数组的最大值就是具有最大和的连续子数组的和 + */ +class Solution { + public int maxSubArray(int[] nums) { + int n = nums.length; + int[] dp = new int[n]; + dp[0] = nums[0]; + for (int i = 1; i < n; i++) { + dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]); + } + return Arrays.stream(dp).max().getAsInt(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0054.java b/leetcode_Java/Solution0054.java new file mode 100644 index 0000000..5854025 --- /dev/null +++ b/leetcode_Java/Solution0054.java @@ -0,0 +1,118 @@ +// 54. 螺旋矩阵 + + +/* +思路同“59.螺旋矩阵II” + +1、指针视角 + left right + ↓ ↓ + top → 1 2 3 4 + 5 6 7 8 + 9 10 11 12 +bottom → 13 14 15 16 + +2、访问顺序:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 + +3、matrix[行][列]:明确行是谁,列是谁,谁变化 + 顶行:matrix[top][left → right] 不变的是行,变化的是列,列左到右 + 右列:matrix[top → bottom][right] 不变的是列,变化的是行,行上到下 + 底行:matrix[bottom][right → left] 不变的是行,变化的是列,列右到左 + 左列:matrix[bottom → top][left] 不变的是列,变化的是行,行下到上 + +4、此解法最容易理解,算法过程 + 1)先初始化上下左右四个指针 + 2)开始循环遍历,顺时针遍历一圈,每遍历完一行或一列,该行或该列指针向内移动一步,作为新的可遍历边界 + 3)只要 上超过下 或 左超过右,说明已经全部遍历完了,可以结束循环了 + */ +class Solution { + public List spiralOrder(int[][] matrix) { + List res = new ArrayList<>(); + int row = matrix.length, col = matrix[0].length; + int top = 0, bottom = row - 1, left = 0, right = col - 1; + while (true) { + for (int i = left; i <= right; i++) { + res.add(matrix[top][i]); + } + top++; + if (top > bottom) break; + + for (int i = top; i <= bottom; i++) { + res.add(matrix[i][right]); + } + right--; + if (left > right) break; + + for (int i = right; i >= left; i--) { + res.add(matrix[bottom][i]); + } + bottom--; + if (top > bottom) break; + + for (int i = bottom; i >= top; i--) { + res.add(matrix[i][left]); + } + left++; + if (left > right) break; + } + return res; + } +} + + +class Solution { + public List spiralOrder(int[][] matrix) { + List res = new ArrayList<>(); + int row = matrix.length, col = matrix[0].length; + int top = 0, bottom = row - 1, left = 0, right = col - 1; + while(left <= right && top <= bottom){ + for(int i = left; i <= right; i++){ + res.add(matrix[top][i]); + } + top++; + + for(int i = top; i <= bottom ; i++){ + res.add(matrix[i][right]); + } + right--; + + for(int i = right; i >= left && top <= bottom; i--){ + res.add(matrix[bottom][i]); + } + bottom--; + + for(int i = bottom; i >= top && left <= right; i--){ + res.add(matrix[i][left]); + } + left++; + } + return res; + } +} + + +// “剑指Offer_Java 19.顺时针打印矩阵” +class Solution { + public List spiralOrder(int[][] matrix) { + int row = matrix.length; + int col = matrix[0].length; + ArrayList ans = new ArrayList<>(); + // 计算循环次数 + int circle = (Math.min(row, col) - 1) / 2 + 1; + for (int i = 0; i < circle; i++) { + // 添加首行 + for (int j = i; j < col - i; j++) + ans.add(matrix[i][j]); + // 添加尾列 + for (int k = i + 1; k < row - i; k++) + ans.add(matrix[k][col - i - 1]); + // 添加尾行 + for (int m = col - i - 2; (m >= i) && (row - i - 1 != i); m--) + ans.add(matrix[row - i - 1][m]); + // 添加尾列 + for (int n = row - i - 2; (n > i) && (col - i - 1 != i); n--) + ans.add(matrix[n][i]); + } + return ans; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0055.java b/leetcode_Java/Solution0055.java new file mode 100644 index 0000000..313e63a --- /dev/null +++ b/leetcode_Java/Solution0055.java @@ -0,0 +1,52 @@ +// 55. 跳跃游戏 + + +/* +动态规划: +1、题目:给定一个非负整数数组nums,你最初位于数组的第一个下标,数组中的每个元素代表你在该位置可以跳跃的最大长度,判断你是否能够到达最后一个下标。 +2、题目简化:求索引 i 位置可以跳跃的最大长度,该长度是否大于等于最后一个索引位置 +3、定义dp数组:dp[i]表示索引 i 位置能够跳跃到的最大长度 +4、初始化: + 1)dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)dp[0] = nums[0]; +5、状态转移方程:dp[i] = max(dp[i - 1], i + nums[i]); +6、遍历dp数组填表:一个for循环遍历dp数组,根据状态转移方程推断计算未知结果并填表 +7、返回结果:在状态转移前后进行跳跃长度判断以快速得出结果,没希望跳过去、已经足够跳过去 + */ +class Solution { + public boolean canJump(int[] nums) { + int n = nums.length; + int[] dp = new int[n]; + dp[0] = nums[0]; + for (int i = 1; i < n; i++) { + if (dp[i - 1] < i) { + return false; + } + dp[i] = Math.max(dp[i - 1], i + nums[i]); + if (dp[i] >= n - 1) { + return true; + } + } + return true; + } +} + + +/* +贪心/动态规划状态压缩:只用一个变量存储可以跳跃的最远距离,省略整个dp数组的空间 +1、如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点 +2、可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新 +3、如果可以一直跳到最后,就成功了 + */ +class Solution { + public boolean canJump(int[] nums) { + int maxLen = 0; + for (int i = 0; i < nums.length; i++) { + if (maxLen < i) { + return false; + } + maxLen = Math.max(maxLen, i + nums[i]); + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0056.java b/leetcode_Java/Solution0056.java new file mode 100644 index 0000000..64ffb6d --- /dev/null +++ b/leetcode_Java/Solution0056.java @@ -0,0 +1,79 @@ +// 56. 合并区间 + + +/* +遍历区间,加入新区间 或 更新结果数组最后一个区间的右端点值成为新合并区间 +1、先将列表中的区间按照左端点升序排序 +2、遍历二维数组 + 1)第一个区间则直接加入结果数组 + 2)如果 结果数组最后一个区间的右端点 小于 当前区间左端点,说明没有重合,当前区间加入结果数组 + 3)如果 结果数组最后一个区间的右端点 大于等于 当前区间左端点,说明有重合,则更新结果数组最后一个区间右端点的值,该值为两右端点取较大者 +3、列表转数组后返回 + +intervals = [[1,3],[2,6],[8,10],[15,18]] res = [[1,3]] + ↑ +intervals = [[1,3],[2,6],[8,10],[15,18]] res = [[1,6]] + ↑ +intervals = [[1,3],[2,6],[8,10],[15,18]] res = [[1,6],[8,10]] + ↑ +intervals = [[1,3],[2,6],[8,10],[15,18]] res = [[1,6],[8,10],[15,18]] + ↑ + */ +class Solution { + public int[][] merge(int[][] intervals) { + Arrays.sort(intervals, (a, b) -> a[0] - b[0]); + List res = new ArrayList<>(); + for (int[] interval : intervals) { + int size = res.size(); + if (size == 0 || res.get(size - 1)[1] < interval[0]) { + res.add(new int[]{interval[0], interval[1]}); + } else { + res.get(size - 1)[1] = Math.max(res.get(size - 1)[1], interval[1]); + } + } + return res.toArray(new int[res.size()][]); + } +} + + +/* +逻辑同上 + */ +class Solution { + public int[][] merge(int[][] intervals) { + Arrays.sort(intervals, (a, b) -> a[0] - b[0]); + int[][] res = new int[intervals.length][2]; + int index = -1; + for (int[] interval : intervals) { + if (index == -1 || interval[0] > res[index][1]) { + res[++index] = interval; + } else { + res[index][1] = Math.max(res[index][1], interval[1]); + } + } + return Arrays.copyOf(res, index + 1); + } +} + + +/* +先遍历多个区间,更新区间右端点值,找到一个合并区间后加入结果数组 + */ +class Solution { + public int[][] merge(int[][] intervals) { + Arrays.sort(intervals, (a, b) -> a[0] - b[0]); + List res = new ArrayList<>(); + int n = intervals.length; + for (int i = 0; i < n; i++) { + int left = intervals[i][0]; + int right = intervals[i][1]; + while (i < n && right >= intervals[i][0]) { + right = Math.max(right, intervals[i][1]); + i++; + } + i--; + res.add(new int[]{left, right}); + } + return res.toArray(new int[res.size()][]); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0059.java b/leetcode_Java/Solution0059.java new file mode 100644 index 0000000..2f48b62 --- /dev/null +++ b/leetcode_Java/Solution0059.java @@ -0,0 +1,38 @@ +// 59. 螺旋矩阵 II + + +/* +思路同“54.螺旋矩阵” + */ +class Solution { + public int[][] generateMatrix(int n) { + int[][] matrix = new int[n][n]; + int left = 0, right = n - 1, top = 0, bottom = n - 1, num = 1; + while (true) { + for (int i = left; i <= right; i++) { + matrix[top][i] = num++; + } + top++; + if (top > bottom) break; + + for (int i = top; i <= bottom; i++) { + matrix[i][right] = num++; + } + right--; + if (left > right) break; + + for (int i = right; i >= left; i--) { + matrix[bottom][i] = num++; + } + bottom--; + if (top > bottom) break; + + for (int i = bottom; i >= top; i--) { + matrix[i][left] = num++; + } + left++; + if (left > right) break; + } + return matrix; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0062.java b/leetcode_Java/Solution0062.java new file mode 100644 index 0000000..015df52 --- /dev/null +++ b/leetcode_Java/Solution0062.java @@ -0,0 +1,85 @@ +// 62. 不同路径 + + +/* +动态规划二维dp:自底向上 +1、题目:一个机器人位于一个 m x n 网格的左上角,机器人每次只能向下或者向右移动一步,机器人试图达到网格的右下角,问总共有多少条不同的路径? +2、题目简化:求从(0,0)到(m-1,n-1)的不同路径条数 +3、定义dp数组:dp[i][j]表示到达位置(i,j)的不同路径条数 +4、初始化: + 1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)首行首列只有一条路径,初始化为1 +5、状态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 即上方和左方的不同路径条数相加 +6、遍历dp数组填表:两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置不同路径条数并填表,直到终点,获得结果 +7、返回结果:最后一个状态就是结果 + */ +class Solution { + public int uniquePaths(int m, int n) { + int[][] dp = new int[m][n]; + for (int i = 0; i < m; i++) { + dp[i][0] = 1; + } + for (int j = 0; j < n; j++) { + dp[0][j] = 1; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; + } + } + return dp[m - 1][n - 1]; + } +} + + +/* +动态规划状态压缩:自底向上 +1、由于每次状态更新只用到上一行的记录,因此可以压缩成一维数组 +2、滚动数组:二维数组更新变成在一维数组上滚动更新 +3、dp[j-1]表示当前行刚更新的值(左方元素),dp[j]表示上一行的旧值(上方元素),相加后覆盖dp[j]表示上一行用过了不需要了 + */ +class Solution { + public int uniquePaths(int m, int n) { + int[] dp = new int[n]; + Arrays.fill(dp, 1); + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[j] += dp[j - 1]; + } + } + return dp[n - 1]; + } +} + + +/* +递归 + 备忘录:自顶向下 +1、定义二维数组作为备忘录,初始化为-1,记录递归过程已经计算路径的位置,防止重复递归计算 +2、从终点位置开始,递归计算路径条数 +2、定义递归函数 + 1)递归函数含义:dfs(i,j)表示到达位置(i,j)的不同路径条数 + 2)终止条件:碰到左边界或上边界就返回1,或者该位置备忘录有值则直接返回 + 3)递归调用:(i,j)位置的不同路径条数由上方和左方的不同路径条数相加,计算完结果存入备忘录并返回结果 + */ +class Solution { + public int uniquePaths(int m, int n) { + int[][] memo = new int[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + memo[i][j] = -1; + } + } + return dfs(memo, m - 1, n - 1); + } + + private int dfs(int[][] memo, int i, int j) { + if (i == 0 || j == 0) { + return 1; + } + if (memo[i][j] != -1) { + return memo[i][j]; + } + memo[i][j] = dfs(memo, i - 1, j) + dfs(memo, i, j - 1); + return memo[i][j]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0064.java b/leetcode_Java/Solution0064.java new file mode 100644 index 0000000..2b030dc --- /dev/null +++ b/leetcode_Java/Solution0064.java @@ -0,0 +1,31 @@ +// 64. 最小路径和 + + +/* +动态规划: +1、题目:给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。 +2、题目简化:求从 (0,0) 到达 (m-1,n-1) 位置的最小路径和 +3、定义dp数组:本题可以直接在原数组操作。grid[i][j] 表示到达 (i,j) 位置的最小路径和 +4、初始化: + 1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)首行首列的路径和进行累加初始化 +5、状态转移方程:grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]); 即上方或左方的最小路径和 +6、遍历顺序:两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最小路径和并填表,直到终点,获得结果 + */ +class Solution { + public int minPathSum(int[][] grid) { + int n = grid.length, m = grid[0].length; + for (int i = 1; i < n; i++) { + grid[i][0] += grid[i - 1][0]; + } + for (int j = 1; j < m; j++) { + grid[0][j] += grid[0][j - 1]; + } + for (int i = 1; i < n; i++) { + for (int j = 1; j < m; j++) { + grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]); + } + } + return grid[n - 1][m - 1]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0069.java b/leetcode_Java/Solution0069.java new file mode 100644 index 0000000..a626116 --- /dev/null +++ b/leetcode_Java/Solution0069.java @@ -0,0 +1,70 @@ +// 69. x 的平方根 + + +/* +二分查找: +1、while条件left<=right,等号要加上,包含了x=0的情况时left==right +2、每次找到中点,比较 中点的平方 与 x 的大小,决定区间缩小的方向 +3、返回值小数会被省去,中点 可能刚好是目标值 或 可能就是最后一个平方小于x的值,所以每次都要保存中点防止丢失 +4、中点的平方可能数值较大,超过int范围导致溢出,所以需要先强转为long类型再计算,比较大小时x自动从int类型向上转型为long类型 + */ +class Solution { + public int mySqrt(int x) { + int left = 0, right = x, res = -1; + while (left <= right) { + int mid = (left + right) / 2; + if ((long) mid * mid <= x) { + res = mid; + left = mid + 1; + } else { + right = mid - 1; + } + } + return res; + } +} + + +/* +牛顿迭代:从大到小逼近 +1、求根号x的近似值res,先令 res 为 x,即从一个大数开始迭代逼近,不断令 res 等于 (res+x/res)/2,由于是向下取整,当 res * res <= x时,此时res为最终结果值 +2、res要用long类型,计算过程如果为整型会溢出,最后结果再强转为整型即可 + + x = 5 +res = 5 → 3 → 2 + */ +class Solution { + public int mySqrt(int x) { + long res = x; + while (res * res > x) { + res = (res + x / res) / 2; + } + return (int) res; + } +} + + +/* +暴力:从小到大逼近 +1、从1开始,平方值小于等于x,则继续查找,直到第一个平方值大于x结束循环,返回前一个值 +2、平方值可能会溢出,要转为long类型 + */ +class Solution { + public int mySqrt(int x) { + long res = 1; + while (res * res <= x) { + res++; + } + return (int) res - 1; + } +} + + +/* +库函数 + */ +class Solution { + public int mySqrt(int x) { + return (int) Math.pow(x, 0.5); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0070.java b/leetcode_Java/Solution0070.java new file mode 100644 index 0000000..446b7c5 --- /dev/null +++ b/leetcode_Java/Solution0070.java @@ -0,0 +1,39 @@ +// 70. 爬楼梯 + + +/* +递推思路: +1、规律:1,2,3,5,8 后一个数是前两个数的和 +2、初始化两个值,根据规律逐渐推算出第n个数的值 + */ +class Solution { + public int climbStairs(int n) { + int a = 1, b = 1; + int temp; + while (n > 1) { + temp = b; + b += a; + a = temp; + n -= 1; + } + return b; + } +} + + +/* +动态规划思路: +1、dp[i]表示i阶楼梯的方法数量 +2、初始条件:dp[0] = dp[1] = 1 +3、状态转移方程:dp[i] = dp[i - 1] + dp[i - 2] + */ +class Solution { + public int climbStairs(int n) { + int[] dp = new int[n + 1]; + dp[0] = dp[1] = 1; + for (int i = 2; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0072.java b/leetcode_Java/Solution0072.java new file mode 100644 index 0000000..23afdb7 --- /dev/null +++ b/leetcode_Java/Solution0072.java @@ -0,0 +1,124 @@ +// 72. 编辑距离 + + +/* +动态规划:自底向上 +1、题目:给你两个单词word1和word2,请返回将word1转换成word2所使用的最少操作数。你可以对一个单词进行如下三种操作:插入一个字符、删除一个字符、替换一个字符 +2、题目简化:求字符串word1转换字符串word2的最少操作数 +3、定义dp数组: + 1)dp[i][j] 表示 word1 前 i 个字符转换成 word2 前 j 个字符使用的最少操作数 + 2)扩增dp数组,int[][] dp = new int[n+1][m+1],dp[0][0]表示两个都是空字符,首行首列表示至少其中一个字符串为空字符的情况 + 3)注意第 i 个字符在字符串中为 word1.charAt(i - 1),索引从0开始 +4、初始化: + 1)二维dp数组扩容:增加空字符串这一最小规模的情况,方便直观初始化 + 2)第一行是word1为空,word1转换成word2使用的最少操作数,就是插入操作 + 3)第一列是word2为空,word1转换成word2使用的最少操作数,就是删除操作 + 4)首行首列操作数进行累加初始化 +5、状态转移方程: + 1)当 word1[i] == word2[j],由于遍历到了i、j,说明 word1 的 0~i-1 和 word2 的 0~j-1 的匹配结果已经生成,当前两个字符相同,无需任何操作,因此 dp[i][j] = dp[i - 1][j - 1]; + 2)当 word1[i] != word2[j] + ① 替换:word1 的 0~i-1 位置与 word2 的 0~j-1 位置的字符都相同,只是当前位置的字符不匹配,进行替换操作后两者变得相同,因此 dp[i][j] = dp[i - 1][j - 1] + 1; + ② 删除:若此时 word1 的 0~i-1 位置与 word2 的 0~j 位置已经匹配了,此时多出了 word1 的 i 位置字符,应把它删除掉两者才变得相同,因此 dp[i][j] = dp[i - 1][j] + 1; + ③ 插入:若此时 word1 的 0~i 位置只是和 word2 的 0~j-1 位置匹配,此时只需要在 word1 的 i 位置后面插入一个和 word2 的 j 位置相同的字符,使得两者变得相同,因此 dp[i][j] = dp[i][j - 1] + 1; + 注:加1表示执行一次操作 +6、举例:以 word1 为 "horse",word2 为 "ros",且 dp[5][3] 为例,即要将 word1 的前 5 个字符转换为 word2 的前 3 个字符,也就是将 horse 转换为 ros,因此有: + 1)dp[i-1][j-1] 表示替换操作,即先将 word1 的前 4 个字符 hors 转换为 word2 的前 2 个字符 ro,然后将 word1 第五个字符替换成 word2 的第三个字符,即由 e 替换为 s + 2)dp[i][j-1] 表示删除操作,即先将 word1 的前 5 个字符 horse 转换为 word2 的前 2 个字符 ro,然后在末尾插入一个 s + 3)dp[i-1][j] 表示插入操作,即先将 word1 的前 4 个字符 hors 转换为 word2 的前 3 个字符 ros,然后删除 word1 的第 5 个字符 +7、遍历dp数组填表: + 1)两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最少操作数 + 2)遍历顺序决定了哪些位置是计算过的、是已知状态,外层遍历word1,内层遍历word2。 + 从二维数组角度看,遍历顺序是从上到下,从左到右,所以遍历到(i,j)位置时,其左方、上方、左上方状态都已经遍历计算过了。 + 从两个字符串角度看,两个指针分别指向两个字符串,两者遍历顺序都是从左到右,所以遍历到(i,j)位置时,其左边其他位置都遍历计算过了。 + 所以求 dp[i][j] 时,dp[i - 1][j - 1]、dp[i - 1][j]、dp[i][j - 1] 都是已知状态了 +8、返回结果:最后一个状态就是结果 + +word1 = "horse", word2 = "ros" + '' r o s +'' 0 1 2 3 +h 1 1 2 3 +o 2 2 1 2 +r 3 2 2 2 +s 4 3 3 2 +e 5 4 4 3 + + word1[i] == word2[j] word1[i] != word2[j] +word1: h r o s e h r o s e + ↑ ↑ + i i +word2: r o s r o s + ↑ ↑ + j j + */ +class Solution { + public int minDistance(String word1, String word2) { + int n = word1.length(), m = word2.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i < n + 1; i++) { + dp[i][0] = dp[i - 1][0] + 1; + } + for (int j = 1; j < m + 1; j++) { + dp[0][j] = dp[0][j - 1] + 1; + } + for (int i = 1; i < n + 1; i++) { + for (int j = 1; j < m + 1; j++) { + if (word1.charAt(i - 1) == word2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])); + } + } + } + return dp[n][m]; + } +} + + + +/* +递归:自顶向下 +1、定义并初始化备忘录数组,作用相当于dp数组 +2、使用两个指针i、j分别指向两个字符串的末尾,逐步向前移动 +3、定义递归函数 + 1)函数定义:dfs(i,j) 输入参数 word1 的位置 i 和 word2 的位置 j,返回 word1[0..i] 和 word2[0..j] 的最小编辑距离 + 2)终止条件:一个字符串遍历完,则返回另一个字符剩余字符个数,表示全部删除或全部插入,都刚好遍历完则是返回0 + 3)查找备忘录,有计算过则快速返回 + 4)调用递归函数计算(i,j)的最小编辑距离,结果保存在备忘录中,并返回结果 + +word1: h r o s e + ↑ + i +word2: r o s + ↑ + j + */ +class Solution { + public int minDistance(String word1, String word2) { + int n = word1.length(), m = word2.length(); + int[][] memo = new int[n][m]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + memo[i][j] = -1; + } + } + return dfs(word1, word2, n - 1, m - 1, memo); + } + + private int dfs(String word1, String word2, int i, int j, int[][] memo) { + if (i == -1) { + return j + 1; + } + if (j == -1) { + return i + 1; + } + if (memo[i][j] != -1) { + return memo[i][j]; + } + if (word1.charAt(i) == word2.charAt(j)) { + memo[i][j] = dfs(word1, word2, i - 1, j - 1, memo); + } else { + memo[i][j] = 1 + Math.min(dfs(word1, word2, i - 1, j - 1, memo), Math.min(dfs(word1, word2, i, j - 1, memo), dfs(word1, word2, i - 1, j, memo))); + } + return memo[i][j]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0075.java b/leetcode_Java/Solution0075.java new file mode 100644 index 0000000..ab30ca6 --- /dev/null +++ b/leetcode_Java/Solution0075.java @@ -0,0 +1,60 @@ +// 75. 颜色分类 + + +/* +单指针:两次遍历,第一次把0交换到前面,第二次把1交换到前面 + */ +class Solution { + public void sortColors(int[] nums) { + int index = 0, n = nums.length; + for (int i = 0; i < n; i++) { + if (nums[i] == 0) { + swap(nums, i, index); + index++; + } + } + for (int i = index; i < n; i++) { + if (nums[i] == 1) { + swap(nums, i, index); + index++; + } + } + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} + + +/* +双指针: +1、p0、p2指针分别指向首尾 +2、遍历到p2指针位置时结束,防止交换完的元素2又被错误地换到前面 +3、由于可能存在2换2的情况,使用while循环将元素2交换到尾部,确保当前位置不是元素2 +4、当前位置的元素2交换完后,再判断交换元素0到头部 + */ +class Solution { + public void sortColors(int[] nums) { + int n = nums.length; + int p0 = 0, p2 = n - 1; + for (int i = 0; i <= p2; i++) { + while (i <= p2 && nums[i] == 2) { + swap(nums, i, p2); + p2--; + } + if (nums[i] == 0) { + swap(nums, i, p0); + p0++; + } + } + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0076.java b/leetcode_Java/Solution0076.java new file mode 100644 index 0000000..1f91dce --- /dev/null +++ b/leetcode_Java/Solution0076.java @@ -0,0 +1,75 @@ +// 76. 最小覆盖子串 + + +/* +双指针,滑动窗口: +步骤一:不断增加 r 使滑动窗口增大,直到窗口包含了t的所有字符 +步骤二:不断增加 l 使滑动窗口缩小,因为是要求最小字串,所以将不必要的字符排除在外,使长度减小,直到碰到一个必须包含的字符,这个时候不能再去掉了,再去掉就不满足条件了,记录此时滑动窗口的长度,并保存最小值 +步骤三:让 l 再增加一个位置,这时滑动窗口肯定不满足条件了,那么继续从步骤一开始执行,寻找新的满足条件的滑动窗口,如此反复,直到 r 超出了字符串s范围 + +算法过程: +1、变量含义: + l: 滑动窗口左边界 + r: 滑动窗口右边界 + size: 最小窗口的长度 + count: 当前窗口字符总需求量。当次遍历中还需要几个字符才能够满足包含t中所有字符的条件,最大也就是t的长度 + start: 最小窗口起始位置。如果有效更新滑动窗口,记录这个窗口的起始位置,方便后续找子串 + need:字符需求量数组。正数表示有需求,负数表示有冗余。字符加入窗口时字符需求量减1,移出窗口时字符需求量加1 +2、遍历t字符串,记录字符个数,表示窗口中字符的需求量 +3、循环条件,右指针向右移动,不超过s的长度 +4、右边界字符,如果需求量大于0,则更新count减1,表示字符加入了窗口,总需求量减1 +5、每次遍历到的字符,在need数组中该字符需求量减1 +6、如果总需求量count为0,说明当前窗口已经包含了t的所有字符 + 1)左边界字符有冗余时,则字符需求量加1,左指针右移,缩小窗口大小,字符移出窗口,循环处理 + 2)如果当前窗口大小 小于 历史最小窗口,则记录当前最小窗口大小,并将记录此时的左边界位置 + 3)左边界字符需求量加1,左边界右移,总需求量count减1,使得当前窗口不包含t的所有字符,重新开始寻找新的满足条件的窗口 +7、右边界右移,进入下一轮循环处理 + +s = "DOABECODEBANC", t = "ABC" + D O A B E C O D E B A N C + ↑ + l/r +============== 步骤一 =================== + D O A B E C O D E B A N C + ↑ ↑ + l r +============== 步骤二 =================== + D O A B E C O D E B A N C + ↑ ↑ + l r +============== 步骤三 =================== + D O A B E C O D E B A N C + ↑ ↑ + l r + */ +class Solution { + public String minWindow(String s, String t) { + int[] need = new int[128]; + for (char c : t.toCharArray()) { + need[c]++; + } + int l = 0, r = 0, count = t.length(), start = 0, size = Integer.MAX_VALUE; + while (r < s.length()) { + char c = s.charAt(r); + if (need[c] > 0) { + count--; + } + need[c]--; + if (count == 0) { + while (need[s.charAt(l)] < 0) { + need[s.charAt(l)]++; + l++; + } + if (r - l + 1 < size) { + size = r - l + 1; + start = l; + } + need[s.charAt(l)]++; + l++; + count++; + } + r++; + } + return size == Integer.MAX_VALUE ? "" : s.substring(start, start + size); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0077.java b/leetcode_Java/Solution0077.java new file mode 100644 index 0000000..73fb5a8 --- /dev/null +++ b/leetcode_Java/Solution0077.java @@ -0,0 +1,62 @@ +// 77. 组合 + + +/* +回溯: +1、定义全局变量res列表存放所有结果,定义全局变量track列表存放子结果 +2、调用递归函数处理得到结果,返回结果 +3、定义递归函数: + 1)终止条件:存放子结果 + 2)一层for循环 + 递归 = n层for循环 + 3)直接通过参数n控制递归下一层的元素区间 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> combine(int n, int k) { + backtrack(n, k); + return res; + } + + public void backtrack(int n, int k) { + if (track.size() == k) { + res.add(new ArrayList<>(track)); + return; + } + for (int i = n; i > 0; i--) { + track.addLast(i); + backtrack(i - 1, k); + track.remove(); + } + } +} + + +/* +回溯: +1、通过index索引变量控制递归下一层的元素区间 +2、增加剪枝条件,提前排除无效遍历 + */ +class Solution { + + private List> res = new ArrayList<>(); + private List track = new ArrayList<>(); + + public List> combine(int n, int k) { + backtrack(n, 1, k); + return res; + } + + private void backtrack(int n, int startIndex, int k) { + if (k == 0) { // 终止条件 + res.add(new ArrayList<>(track)); // 收集子结果 + return; + } + for (int i = startIndex; i <= n - k + 1; i++) { // for循环控制树的横向遍历 + track.add(i); // 处理节点 + backtrack(n, i + 1, k - 1); // 递归控制树的纵向遍历 + track.remove(track.size() - 1); // 回溯,撤销节点 + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0078.java b/leetcode_Java/Solution0078.java new file mode 100644 index 0000000..1afe667 --- /dev/null +++ b/leetcode_Java/Solution0078.java @@ -0,0 +1,75 @@ +// 78. 子集 + + +/* +回溯: +1、不需要剪枝,求子集的过程就是要遍历整棵树 +2、不需要终止条件,startIndex达到数组长度时for循环就自动终止了 +3、求子集,则每做一次选择就要收集一次结果 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> subsets(int[] nums) { + backtrack(nums, 0); + return res; + } + + private void backtrack(int[] nums, int startIndex) { + res.add(new ArrayList<>(track)); + for (int i = startIndex; i < nums.length; i++) { + track.addLast(nums[i]); + backtrack(nums, i + 1); + track.removeLast(); + } + } +} + + +/* +回溯: +1、通过递归实现遍历数组,方法参数传入数组索引 +2、每个元素有加入和不加入两种可能,通过两次回溯递归处理两种情况 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> subsets(int[] nums) { + backtrack(nums, 0); + return res; + } + + private void backtrack(int[] nums, int index) { + if (index == nums.length) { + res.add(new ArrayList(track)); + return; + } + track.addLast(nums[index]); + backtrack(nums, index + 1); + track.removeLast(); + backtrack(nums, index + 1); + } +} + + +/* +迭代: +两层for循环遍历数组,将当前所有子集加上该数,构成新的子集,遍历结束后即可获得数组所有子集 + */ +class Solution { + public List> subsets(int[] nums) { + List> res = new ArrayList<>(); + res.add(new ArrayList<>()); + for (int i = 0; i < nums.length; i++) { + int size = res.size(); + for (int j = 0; j < size; j++) { + List temp = new ArrayList<>(res.get(j)); + temp.add(nums[i]); + res.add(temp); + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0079.java b/leetcode_Java/Solution0079.java new file mode 100644 index 0000000..3e55612 --- /dev/null +++ b/leetcode_Java/Solution0079.java @@ -0,0 +1,56 @@ +// 79. 单词搜索 + + +/* +深度优先搜索,回溯: +1、把递归方法用到的公共变量作为成员变量,避免入参冗杂,入参只保留方法独用的局部变量 +2、遍历字符网格,以每个字符作为单词搜索的起点,搜索成功返回true,遍历完后仍未搜索成功则返回false +3、定义递归函数: + 1)终止条件: + ① 索引等于单词长度,表示搜索成功结束,返回true + ② 网格越界、网格字符已访问、网格字符与单词字符不同,返回false + 2)递归回溯: + ① 未达到终止条件前,需要继续搜索。先标记当前位置已访问,然后从上下左右四个方向继续搜索,获取搜索结果进行或运算,表示其中一个搜索成功即为成功 + ② 如果四个方向都搜索失败,需要重新标记当前位置未访问,不影响其他递归搜索,即回溯 + ③ 将搜索结果返回给上一层 + */ +class Solution { + private char[][] board; + private String word; + private int m, n; + private boolean[][] visited; + + public boolean exist(char[][] board, String word) { + this.board = board; + this.m = board.length; + this.n = board[0].length; + this.word = word; + this.visited = new boolean[m][n]; + for (int row = 0; row < m; row++) { + for (int col = 0; col < n; col++) { + if (dfs(0, row, col)) { + return true; + } + } + } + return false; + } + + private boolean dfs(int index, int row, int col) { + if (index == word.length()) { + return true; + } + if (row < 0 || row >= m || col < 0 || col >= n || visited[row][col] || word.charAt(index) != board[row][col]) { + return false; + } + visited[row][col] = true; + boolean res = dfs(index + 1, row + 1, col) + || dfs(index + 1, row - 1, col) + || dfs(index + 1, row, col + 1) + || dfs(index + 1, row, col - 1); + if (!res) { + visited[row][col] = false; + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0081.java b/leetcode_Java/Solution0081.java new file mode 100644 index 0000000..b2234eb --- /dev/null +++ b/leetcode_Java/Solution0081.java @@ -0,0 +1,43 @@ +// 81. 搜索旋转排序数组 II + + +/* +1、二分查找,比“33. 搜索旋转排序数组”多了重复元素 +2、二分的本质是「二段性」,并非单调性。只要一段满足某个性质,另外一段不满足某个性质,就可以用「二分」,再利用性质去判断选择收缩区间 +3、分类讨论举例 + 1)第一类:1011110111 和 1110111101。此种情况下 nums[start] == nums[mid],分不清到底是前面有序还是后面有序,此时 left++ 即可,相当于去掉一个重复的干扰项 + 2)第二类:2345671。也就是 nums[left] < nums[mid],此例子中就是 2 < 5,这种情况下,左半部分有序 + 因此如果 nums[left] <= target < nums[mid],则在左半部分找,否则去右半部分找 + 3)第三类:6712345。也就是 nums[left] > nums[mid],此例子中就是 6 > 2,这种情况下,右半部分有序 + 因此如果 nums[mid] < target <= nums[right],则在右半部分找,否则去前半部分找 + */ +class Solution { + public boolean search(int[] nums, int target) { + int n = nums.length; + int left = 0, right = n - 1; + while (left <= right) { // 可能剩下最后一个数,也要判断是否为目标值,所以要等号 + int mid = (left + right) / 2; // (left + right + 1) / 2 也可以,因为中点值判断过不满足就舍弃,所以不会存在重复中点死循环问题 + if (nums[mid] == target) { // 判断中点是否为目标值,是则返回true + return true; + } + if (nums[left] == nums[mid]) { // 由于存在重复元素,左值与中值相等时,无法区分二段性,让左指针右移,去掉一个重复的干扰项 + left++; + continue; + } + if (nums[left] < nums[mid]) { // 左半部分有序。等号的情况上面已经判断了,这里就不用等号了 + if (nums[left] <= target && target < nums[mid]) { // 目标值在左半部分。[left,mid) 因为左值还没判断,中值已经判断过了 + right = mid - 1; // 收缩右区间,中值已经判断过不满足了,不需要包含 + } else { // 目标值在右半部分 + left = mid + 1; // 收缩左区间,中值已经判断过不满足了,不需要包含 + } + } else { // 右半部分有序 + if (nums[mid] < target && target <= nums[right]) { // 目标值在右半部分。(mid,right] 因为右值还没判断,中值已经判断过了 + left = mid + 1; // 收缩左区间,中值已经判断过不满足了,不需要包含 + } else { // 目标值在左半部分 + right = mid - 1; // 收缩右区间,中值已经判断过不满足了,不需要包含 + } + } + } + return false; // 没有找到目标值,返回false + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0082.java b/leetcode_Java/Solution0082.java new file mode 100644 index 0000000..15e25b1 --- /dev/null +++ b/leetcode_Java/Solution0082.java @@ -0,0 +1,127 @@ +// 82. 删除排序链表中的重复元素 II + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +递归: +1、方法功能:入参是一个节点,判断该节点是否重复,不重复则返回该节点,否则往下遍历找到第一个与该节点不相同的节点后返回 +2、终止条件:节点为空 或 下一节点为空,则直接返回,因为至少需要两个节点才需要判断删除 +3、递归逻辑:先根据一个节点的情况进行处理,处理完后下一节点同样需要判断处理,则调用同样的方法递归处理 + */ +class Solution { + public ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) { + return head; + } + if (head.val != head.next.val) { + head.next = deleteDuplicates(head.next); + return head; + } else { + ListNode temp = head.next; + while (temp != null && head.val == temp.val) { + temp = temp.next; + } + return deleteDuplicates(temp); + } + } +} + + +/* +一次遍历,改变节点指针: +1、至少要有两个节点才需要判断删除,否则直接返回 +2、初始化pre、cur的位置,两者相邻。pre表示前一个有效节点的指针 +3、当cur下一节点值与当前相同时,则cur继续往右走,走到最后一个值相同的节点 +4、如果pre下一节点还是cur,说明中间没有重复节点,pre往右走一步即可。 + 如果pre下一节点不是cur,说明中间有重复节点,包括cur在内的节点都要删除,即pre下一指针指向cur下一指针节点。此时pre还不能动,因为新的cur可能还是重复节点 +5、经过一轮判断处理后,cur往右走一步。此时pre、cur回到初始状态 + + 0 → 1 → 2 → 3 → 3 → 4 → 4 → 5 +root/pre cur +=========================================================== + 0 → 1 → 2 → 3 → 3 → 4 → 4 → 5 +root pre cur +=========================================================== + 0 → 1 → 2 → 3 → 3 → 4 → 4 → 5 +root pre cur +=========================================================== + 0 → 1 → 2 → 3 → 3 → 4 → 4 → 5 +root pre cur +=========================================================== + 0 → 1 → 2 → 4 → 4 → 5 +root pre cur +=========================================================== + 0 → 1 → 2 → 4 → 4 → 5 +root pre cur +=========================================================== + 0 → 1 → 2 → 5 +root pre cur +=========================================================== + 0 → 1 → 2 → 5 +root pre cur + */ +class Solution { + public ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode root = new ListNode(0, head); + ListNode pre = root, cur = head; + while (cur != null) { + while (cur.next != null && cur.val == cur.next.val) { + cur = cur.next; + } + if (pre.next == cur) { + pre = pre.next; + } else { + pre.next = cur.next; + } + cur = cur.next; + } + return root.next; + } +} + + +/* +记录个数,改变节点指针: +1、上一解法是cur直接走到最后一个重复节点位置,一次性跳过多个重复节点 + 当前解法是cur一步一步走,根据map中记录的出现次数决定是否跳过cur节点 +2、先遍历一次,记录每个节点值出现次数 +3、再次遍历,如果节点出现次数大于1则跳过 + */ +class Solution { + public ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) { + return head; + } + Map map = new HashMap<>(); + ListNode temp = head; + while (temp != null) { + map.put(temp.val, map.getOrDefault(temp.val, 0) + 1); + temp = temp.next; + } + ListNode root = new ListNode(0, head); + ListNode pre = root, cur = head; + while (cur != null) { + if (map.get(cur.val) == 1) { + pre = pre.next; + } else { + pre.next = cur.next; + } + cur = cur.next; + } + return root.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0083.java b/leetcode_Java/Solution0083.java new file mode 100644 index 0000000..0e9243d --- /dev/null +++ b/leetcode_Java/Solution0083.java @@ -0,0 +1,53 @@ +// 83. 删除排序链表中的重复元素 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +1、创建哨兵节点标记链表头部,用于删除节点后返回链表 +2、使用前后两个指针pre、head来标记节点位置,通过判断head不为空来循环遍历,从而保证能获取前后两个节点的值来判断 + */ +class Solution { + public ListNode deleteDuplicates(ListNode head) { + ListNode root = new ListNode(-101, head); + ListNode pre = root; + while (head != null) { + if (head.val == pre.val) { + pre.next = head.next; + } else { + pre = head; + } + head = head.next; + } + return root.next; + } +} + + +/* +1、head为链表头部不变,用于删除节点后返回链表 +2、使用一个指针cur标记节点,通过判断cur和cur.next不为空来循环遍历,从而保证能获取前后两个节点的值来判断 + */ +class Solution { + public ListNode deleteDuplicates(ListNode head) { + ListNode cur = head; + while (cur != null && cur.next != null) { + if (cur.val == cur.next.val) { + cur.next = cur.next.next; + } else { + cur = cur.next; + } + } + return head; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0084.java b/leetcode_Java/Solution0084.java new file mode 100644 index 0000000..5699b12 --- /dev/null +++ b/leetcode_Java/Solution0084.java @@ -0,0 +1,92 @@ +// 84. 柱状图中最大的矩形 + + +/* +暴力: +1、数组扩容,首尾添加哨兵0元素,作为最低点,方便作为任意高度的左右边界 +2、遍历柱子高度,对于每一个柱子高度分别向两边扩散,求出当前高度为矩形的最大宽度 +3、最大宽度的 左边界是当前柱子向左遍历第一个低于当前柱子高度的位置,右边界是当前柱子向右遍历第一个低于当前柱子高度的位置,左右边界的距离就是最大宽度 +4、当前柱子最大面积 = 最大宽度 * 当前柱子高度,比较并保存最大面积 + +高度: 0 2 1 5 6 2 3 0 +索引: 0 1 2 3 4 5 6 7 + ↑ ↑ ↑ + left i right +(right - left - 1) * newHeights[i] = (5-2-1)*5 = 10 + */ +class Solution { + public int largestRectangleArea(int[] heights) { + int res = 0; + int n = heights.length; + int[] newHeights = new int[n + 2]; + for (int i = 0; i < n; i++) { + newHeights[i + 1] = heights[i]; + } + for (int i = 1; i < n + 1; i++) { + int left = i - 1; + while (left > 0 && newHeights[i] <= newHeights[left]) { + left--; + } + int right = i + 1; + while (right < n + 2 && newHeights[i] <= newHeights[right]) { + right++; + } + int area = (right - left - 1) * newHeights[i]; + res = Math.max(res, area); + } + return res; + } +} + + +/* +单调栈 +1、单调栈分为单调递增栈和单调递减栈 + 1)单调递增栈,即栈内元素保持单调递增的栈 + 2)单调递减栈,即栈内元素保持单调递减的栈 +2、操作规则(下面都以单调递增栈为例) + 1)如果新元素比栈顶元素大,就入栈 + 2)如果新元素比栈顶元素小,那就一直把栈顶元素弹出来,直到栈顶元素比新元素小,然后新元素入栈 +3、规则效果(举例:栈[1, 5, 6],新元素2) + 1)栈内的元素是递增的 + 2)当元素出栈时,这个新元素是出栈元素向右找第一个比它小的元素(2是6右边第一个比它小的元素) + 3)当元素出栈后,新栈顶元素是出栈元素向左找第一个比它小的元素(5是6左边第一个比它小的元素) +4、使用单调栈的场景 + 1)需要查找数组每个元素左或右边第一个比它大或小的元素和索引时,可以用单调栈 + 2)利用栈存放索引,这样既可以通过索引获取索引差值,也可以通过索引从数组获取元素值 + 3)查找第一个比它大的元素时,用单调递减栈。因为新元素比它小时会入栈,形成单调递减栈,比它大时会出栈。 + 4)查找第一个比它小的元素时,用单调递增栈。因为新元素比它大时会入栈,形成单调递增栈,比它小时会出栈。 + */ + + +/* +单调递增栈: +1、暴力解法每次都要重新求当前柱子的左右边界,时间复杂度O(n²),空间复杂度O(1) + 核心思路是要找到当前柱子的左右边界 左边第一个高度小于它的位置 和 右边第一个高度小于它的位置,因此可以利用单调递增栈的特性,时间复杂度O(1),空间复杂度O(n) +2、数组扩容,首尾添加哨兵0元素,作为最低点,方便作为任意高度的左右边界 +3、利用栈存放索引,这样既可以通过索引差获取宽度,也可以通过索引从数组获取高度 +3、遍历数组 + 1)栈为空 或 当前高度大于栈顶高度 则当前索引入栈 + 2)栈不为空 且 当前高度小于栈顶高度,则弹出栈顶高度作为矩形高度,新栈顶索引是左边界,当前索引是右边界,计算面积并保存最大面积。 + 循环弹出处理,直到新栈顶高度比当前高度小,最后当前索引入栈,保证了栈内元素单调递增 +4、单调递增栈使得每一个出栈的柱子高度,都能通过 新栈顶索引 和 当前索引 快速获取左右边界,每一个柱子高度都会入栈,从而快速计算了每个柱子高度为矩形的最大面积 + */ +class Solution { + public int largestRectangleArea(int[] heights) { + int res = 0; + int n = heights.length; + int[] newHeights = new int[n + 2]; + System.arraycopy(heights, 0, newHeights, 1, n); + Deque stack = new ArrayDeque<>(); + for (int right = 0; right < n + 2; right++) { + while (!stack.isEmpty() && newHeights[right] < newHeights[stack.peek()]) { + int cur = stack.pop(); + int left = stack.peek(); + int area = (right - left - 1) * newHeights[cur]; + res = Math.max(res, area); + } + stack.push(right); + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0085.java b/leetcode_Java/Solution0085.java new file mode 100644 index 0000000..08dc46d --- /dev/null +++ b/leetcode_Java/Solution0085.java @@ -0,0 +1,125 @@ +// 85. 最大矩形 + + +/* +暴力破解/动态规划: +1、思路:遍历每个点,求以这个点为矩形右下角的所有矩形面积,比较并记录最大面积 +2、二维数组width用于记录每行上每个点结尾的连续 1 的个数,即每行上每个点结尾时的宽度。width可以理解为dp数组,保存状态 +3、从左到右遍历,计算并记录每行上每个点结尾时的宽度 +4、计算面积 + 1)首先求出高度是 1 的矩形面积,即高度只有一行,宽度是该点记录的宽度 + 2)然后向上扩展一行,高度增加1,选出width当前列最小的数字,即多行的宽度选择最小的宽度为有效宽度,作为矩形的宽度,求出面积 + 3)然后继续向上扩展,重复步骤 2,求出所有可能的高度时的面积 + */ +class Solution { + public int maximalRectangle(char[][] matrix) { + int m = matrix.length, n = matrix[0].length; + int maxArea = 0; + int[][] width = new int[m][n]; + for (int row = 0; row < m; row++) { + for (int col = 0; col < n; col++) { + if (matrix[row][col] == '1') { + width[row][col] = col == 0 ? 1 : width[row][col - 1] + 1; + } + int midWidth = width[row][col]; + for (int rowUp = row; rowUp >= 0; rowUp--) { + int height = row - rowUp + 1; + midWidth = Math.min(midWidth, width[rowUp][col]); + maxArea = Math.max(maxArea, midWidth * height); + } + } + } + return maxArea; + } +} + + +/* +暴力破解: +1、遍历每一行的时候,从上往下计算每一列连续1的个数作为矩形高度,得到高度矩阵 +2、遍历高度矩阵,以当前点的值作为矩形高度,向左右两边扩展高度大于等于当前高度的边界得到宽度,从而计算该点的最大面积 +3、比较并记录矩阵所有点的最大面积,得出整个矩阵的最大面积 + */ +class Solution { + public int maximalRectangle(char[][] matrix) { + int m = matrix.length, n = matrix[0].length; + int[][] heights = new int[m][n]; + int maxArea = 0; + for (int col = 0; col < n; col++) { + heights[0][col] = matrix[0][col] == '1' ? 1 : 0; + } + for (int row = 1; row < m; row++) { + for (int col = 0; col < n; col++) { + if (matrix[row][col] == '1') { + heights[row][col] = heights[row - 1][col] + 1; + } + } + } + for (int row = 0; row < m; row++) { + for (int col = 0; col < n; col++) { + if (heights[row][col] == 0 || heights[row][col] * n <= maxArea) { + continue; + } + int width = 1; + for (int k = col - 1; k >= 0; k--) { + if (heights[row][k] < heights[row][col]) { + break; + } + width++; + } + for (int k = col + 1; k < n; k++) { + if (heights[row][k] < heights[row][col]) { + break; + } + width++; + } + maxArea = Math.max(maxArea, width * heights[row][col]); + } + } + return maxArea; + } +} + + +/* +单调递增栈: +1、遍历每一行的时候,从上往下计算每一列连续1的个数作为矩形高度,得到高度数组 +2、直接利用“84. 柱状图中最大的矩形”的解法,传入高度数组,得到最大矩形面积 +3、在所有行的矩形面积结果中,记录最大面积 + */ +class Solution { + public int maximalRectangle(char[][] matrix) { + int m = matrix.length, n = matrix[0].length; + int[] heights = new int[n]; + int maxArea = 0; + for (int row = 0; row < m; row++) { + for (int col = 0; col < n; col++) { + if (matrix[row][col] == '1') { + heights[col] += 1; + } else { + heights[col] = 0; + } + } + maxArea = Math.max(maxArea, largestRectangleArea(heights)); + } + return maxArea; + } + + private int largestRectangleArea(int[] heights) { + int res = 0; + int n = heights.length; + int[] newHeights = new int[n + 2]; + System.arraycopy(heights, 0, newHeights, 1, n); + Deque stack = new ArrayDeque<>(); + for (int right = 0; right < n + 2; right++) { + while (!stack.isEmpty() && newHeights[right] < newHeights[stack.peek()]) { + int cur = stack.pop(); + int left = stack.peek(); + int area = (right - left - 1) * newHeights[cur]; + res = Math.max(res, area); + } + stack.push(right); + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0088.java b/leetcode_Java/Solution0088.java new file mode 100644 index 0000000..527786f --- /dev/null +++ b/leetcode_Java/Solution0088.java @@ -0,0 +1,64 @@ +// 88. 合并两个有序数组 + + +/* +直接合并后排序 + */ +class Solution { + public void merge(int[] nums1, int m, int[] nums2, int n) { + for (int i = 0; i < n; i++) { + nums1[m + i] = nums2[i]; + } + Arrays.sort(nums1); + } +} + + +/* +双指针:创建新的数组空间,两个数组从左到右遍历比较出 较小的元素,从数组前面开始存储。不能在原数组存储,因为元素可能取出前被覆盖 + */ +class Solution { + public void merge(int[] nums1, int m, int[] nums2, int n) { + int[] nums = new int[m + n]; + int p1 = 0, p2 = 0, index = 0; + int num; + while (p1 < m || p2 < n) { + if (p1 == m) { + num = nums2[p2++]; + } else if (p2 == n) { + num = nums1[p1++]; + } else if (nums1[p1] < nums2[p2]) { + num = nums1[p1++]; + } else { + num = nums2[p2++]; + } + nums[index++] = num; + } + for (int i = 0; i < m + n; i++) { + nums1[i] = nums[i]; + } + } +} + + +/* +逆向双指针:数组后半部分是空的,两个数组从右到左遍历比较出 较大的元素,从数组后面开始存储 + */ +class Solution { + public void merge(int[] nums1, int m, int[] nums2, int n) { + int p1 = m - 1, p2 = n - 1, index = m + n - 1; + int num; + while (p1 >= 0 || p2 >= 0) { + if (p1 == -1) { + num = nums2[p2--]; + } else if (p2 == -1) { + num = nums1[p1--]; + } else if (nums1[p1] > nums2[p2]) { + num = nums1[p1--]; + } else { + num = nums2[p2--]; + } + nums1[index--] = num; + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0090.java b/leetcode_Java/Solution0090.java new file mode 100644 index 0000000..0c4c7f2 --- /dev/null +++ b/leetcode_Java/Solution0090.java @@ -0,0 +1,59 @@ +// 90. 子集 II + + +/* +回溯: +1、使用res存放全局结果,使用track存放子结果 +2、要先数组排序,才能判断同元素同一层是否使用过。调用递归函数,返回结果 +3、定义递归函数: + 1)终止条件:求子集,过程每添加一个元素,子结果都要存入res,不用return + 2)剪枝条件:for循环遍历,要判断当前元素跟前一元素是否相同,相同表示当前层该元素在前面用过了,跳过 + 3)做选择加入元素 → 递归下一层 → 回溯移除元素 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + backtrack(nums, 0); + return res; + } + + private void backtrack(int[] nums, int startIndex) { + res.add(new ArrayList<>(track)); + for (int i = startIndex; i < nums.length; i++) { + if (i > startIndex && nums[i] == nums[i - 1]) { + continue; + } + track.addLast(nums[i]); + backtrack(nums, i + 1); + track.removeLast(); + } + } +} + + +/* +迭代: +1、由于元素存在重复,先数组排序,防止元素顺序不同产生新的子集 +2、两层for循环遍历数组,将当前所有子集加上该数,构成新的子集,子集不存在时才加入结果res中,遍历结束后即可获得数组所有子集 + */ +class Solution { + public List> subsetsWithDup(int[] nums) { + List> res = new ArrayList<>(); + res.add(new ArrayList<>()); + Arrays.sort(nums); + for (int i = 0; i < nums.length; i++) { + int size = res.size(); + for (int j = 0; j < size; j++) { + List temp = new ArrayList<>(res.get(j)); + temp.add(nums[i]); + if (!res.contains(temp)) { + res.add(temp); + } + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0092.java b/leetcode_Java/Solution0092.java new file mode 100644 index 0000000..4b403d2 --- /dev/null +++ b/leetcode_Java/Solution0092.java @@ -0,0 +1,69 @@ +// 92. 反转链表 II + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +“25.K个一组翻转链表”是反转多次,逻辑相似 +1、指针含义 + 1)root:哨兵节点 + 2)pre:反转区域前的尾节点 + 3)start:反转区域的头节点 + 4)end:反转区域的尾节点 + 5)next:反转区域后的头节点 +2、pre、end根据给定的区域范围走到指定位置,标记start、next +3、end下一指针指向空,使得反转区域链表独立 +4、反转区域链表反转,返回新的头节点,pre连接新的头节点end,新的尾节点连接next + + 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 +root/pre/end +============================================================= + 0 → 1 → 2 → 3 → 4 → 5 6 → 7 → 8 +root pre start end next +============================================================= + 0 → 1 → 2 → 5 → 4 → 3 → 6 → 7 → 8 +root pre end start next + */ +class Solution { + public ListNode reverseBetween(ListNode head, int left, int right) { + if (left == right) { + return head; + } + ListNode root = new ListNode(0, head); + ListNode pre = root, end = root, start, next; + for (int i = 1; i < left; i++) { + pre = pre.next; + } + for (int i = 0; i < right; i++) { + end = end.next; + } + next = end.next; + start = pre.next; + end.next = null; + pre.next = reverse(start); + start.next = next; + return root.next; + } + + // 206.反转链表 + private ListNode reverse(ListNode head) { + ListNode before = null, after; + while (head != null) { + after = head.next; + head.next = before; + before = head; + head = after; + } + return before; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0093.java b/leetcode_Java/Solution0093.java new file mode 100644 index 0000000..589257c --- /dev/null +++ b/leetcode_Java/Solution0093.java @@ -0,0 +1,63 @@ +// 93. 复原 IP 地址 + + +/* +回溯: +1、确定递归参数: + 1)startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置 + 2)还需要一个变量pointNum,记录添加逗点的数量 +2、递归终止条件: + 1)本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。 + 2)pointNum表示逗点数量,pointNum为3说明字符串分成了4段了。然后验证一下第四段是否合法,如果合法就加入到结果集里。 +3、单层递归逻辑: + 1)for循环中[startIndex, i]这个区间就是截取的子串,需要判断这个子串是否合法。如果合法就在字符串后面加上符号.表示已经分割。如果不合法就结束本层循环。 + 2)递归调用时,下一层递归的startIndex要从i+2开始(因为在字符串中加入了分隔符.),同时记录分割符的数量pointNum要加1。回溯的时候pointNum要减1。 + 3)字符串参数在递归函数入参时构造,不影响本层原来的参数,这是回溯隐藏的写法。 + */ +class Solution { + private List res = new ArrayList<>(); + private int pointNum = 0; + + public List restoreIpAddresses(String s) { + backtrack(s, 0); + return res; + } + + private void backtrack(String s, int startIndex) { + if (pointNum == 3) { + if (isValid(s, startIndex, s.length() - 1)) { + res.add(s); + } + return; + } + for (int i = startIndex; i < s.length(); i++) { + if (isValid(s, startIndex, i)) { + pointNum++; + backtrack(s.substring(0, i + 1) + "." + s.substring(i + 1), i + 2); + pointNum--; + } else { + break; + } + } + } + + private boolean isValid(String s, int start, int end) { + if (start > end) { + return false; + } + if (s.charAt(start) == '0' && start != end) { + return false; + } + int num = 0; + for (int i = start; i <= end; i++) { + if (s.charAt(i) > '9' || s.charAt(i) < '0') { + return false; + } + num = num * 10 + (s.charAt(i) - '0'); + if (num > 255) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0094.java b/leetcode_Java/Solution0094.java new file mode 100644 index 0000000..3682563 --- /dev/null +++ b/leetcode_Java/Solution0094.java @@ -0,0 +1,255 @@ +// 94. 二叉树的中序遍历 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、定义数据结构:使用列表成员变量,存储每次递归操作存入的值 +2、递归终止条件:节点为空时返回 +3、单层递归逻辑:把节点的值存入列表 +4、递归逻辑: + 左右节点需要与根节点做同样的事,就要调同样的方法,即递归 + 确定递归顺序/遍历顺序,左中右 + 每层不需要接收使用递归方法返回值,列表成员变量存储了结果 +================================================= +新模板注释,递归 +节点值加入列表递归函数 +1、方法功能:入参是一个节点,将该节点值加入列表,返回列表 +2、终止条件:节点为空时,返回列表 +3、一个节点处理过程和返回结果:将节点值加入列表,返回列表 +4、递归调用:左右节点同样需要加入列表,因此调用同样的方法处理 +5、递归顺序:中序遍历,先处理左节点,再处理根节点,最后处理右节点 +6、使用递归调用结果和返回结果:不用接收递归调用结果,节点已经加入列表了,直接返回列表即可 +* */ +class Solution { + public List list = new ArrayList<>(); + public List inorderTraversal(TreeNode root) { + if (root == null) { + return list; + } + inorderTraversal(root.left); + list.add(root.val); + inorderTraversal(root.right); + return list; + } +} + + +/* +* 递归思路:等同上个实现的逻辑 +* */ +class Solution { + public List list = new ArrayList<>(); + public List inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + list.add(root.val); + inorderTraversal(root.right); + } + return list; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:局部变量即可,列表存放结果数据,栈按序存放节点,指针指向下一个要处理的节点 +* 2、遍历条件、操作逻辑: +* 当前节点不为空,节点入栈,指向左节点 +* 栈不为空,弹出节点,存入节点值,指向右节点 +* 3、实现了中序遍历,按序存放节点入栈,按序获取节点值 +* */ +class Solution { + public List inorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + if (cur != null) { + stack.push(cur); + cur = cur.left; + } else { + cur = stack.pop(); + list.add(cur.val); + cur = cur.right; + } + } + return list; + } +} + + +/* +* 迭代思路:等同上个实现的逻辑 +* */ +class Solution { + public List inorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + while (cur != null) { + stack.push(cur); + cur = cur.left; + } + cur = stack.pop(); + list.add(cur.val); + cur = cur.right; + } + return list; + } +} + + +/* +* 1、莫里斯遍历: +* 1)用递归和迭代的方式都使用了辅助的空间,而莫里斯遍历的优点是没有使用任何辅助空间。 +* 2)缺点是改变了整个树的结构,强行把一棵二叉树改成一段链表结构。 +* 2、思路:把根节点接到左子树的最后一个右节点上,形成链表,再遍历获取链表的值 +* 3、相似题:114.二叉树展开为链表,前序遍历 +* */ +class Solution { + public List inorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + while (root != null) { + if (root.left != null) { + TreeNode pre = root.left; + while (pre.right != null) { + pre = pre.right; + } + pre.right = root; + TreeNode temp = root; + root = root.left; + temp.left = null; + } else { + list.add(root.val); + root = root.right; + } + } + return list; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:结果列表存放排序节点值;节点列表按序存放节点;索引列表存放未判断是否有左右子节点的节点 +* 2、数据结构初始化:根节点存入节点列表;索引0存入索引列表 +* 3、迭代逻辑: +* 1)索引列表不为空时,说明有节点未判断是否有左右子节点,循环遍历索引列表 +* 2)索引列表降序排序,取出最大索引,对该索引的节点进行操作。先处理靠右边的节点,可以防止插入节点时影响了节点列表其他节点的位置 +* 3)是否有子节点存在四种情况:有左右节点、只有右节点、只有左节点、没有左右节点。要分别处理,不同情况节点最终索引位置不同 +* 4)中序遍历: +* 先插入右节点,再插入左节点 +* 插入右节点是在根节点右边插入,其他结点右移一位 +* 插入左节点是替代了根节点的位置,根节点和其他结点右移一位 +* 5)最大索引的节点判断完左右节点后,移除索引列表的最大索引 +* 6)最终节点列表按序排序,遍历结点列表,将节点值存入结果列表 +* +* 1 +* / \ +* 2 3 +* / \ +* 4 5 +* 节点列表:1 +* 索引列表:0 +* ==================== +* 节点列表:2 1 3 +* 索引列表:0 2 +* ==================== +* 节点列表:2 1 4 3 5 +* 索引列表:2 5 +* ==================== +* 节点列表:2 1 4 3 5 +* 索引列表: +* */ +public class Solution0094 { + public List inorderTraversal(TreeNode root) { + List resList = new ArrayList<>(); + if (root == null) { + return resList; + } + List nodeList = new ArrayList<>(); + List indexList = new ArrayList<>(); + nodeList.add(root); + indexList.add(0); + while (!indexList.isEmpty()) { + indexList.sort((o1, o2) -> o2 - o1); + int index = indexList.get(0); + root = nodeList.get(index); + if (root.left != null && root.right != null) { + nodeList.add(index + 1, root.right); + nodeList.add(index, root.left); + indexList.add(index + 2); + indexList.add(index); + } else if (root.left != null) { + nodeList.add(index, root.left); + indexList.add(index); + } else if (root.right != null) { + nodeList.add(index + 1, root.right); + indexList.add(index + 1); + } + indexList.remove(0); + } + for (TreeNode node : nodeList) { + resList.add(node.val); + } + return resList; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:列表存放节点值;栈按序存放节点;哈希表标记节点是否已处理过左右节点 +* 2、数据结构初始化:根节点入栈 +* 3、迭代逻辑: +* 1)栈不为空时遍历栈,弹出栈顶节点 +* 2)判断当前节点是否已经处理过左右节点,处理过节点值存入列表 +* 3)没有则将节点按右中左顺序入栈,弹出时才会是左中右,标记当前节点已处理 +* 4、标记目的:节点已经遍历过,但又暂时不能存入列表,所以需要先按序暂存在栈中,按序弹出再存入列表 +* 作用与递归相同,递归是使用栈帧保存当前变量,当下一层处理完成后,就可以回到当前栈帧的状态,处理当前的数据 +* */ +class Solution { + public List inorderTraversal(TreeNode root) { + List resList = new ArrayList<>(); + if (root == null) { + return resList; + } + Map flagMap = new HashMap<>(); + Stack stack = new Stack<>(); + stack.add(root); + while (!stack.isEmpty()) { + root = stack.pop(); + if (flagMap.getOrDefault(root, false)) { + resList.add(root.val); + } else { + if (root.right != null) { + stack.push(root.right); + } + stack.push(root); + if (root.left != null) { + stack.push(root.left); + } + flagMap.put(root, true); + } + } + return resList; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0096.java b/leetcode_Java/Solution0096.java new file mode 100644 index 0000000..d8135fd --- /dev/null +++ b/leetcode_Java/Solution0096.java @@ -0,0 +1,62 @@ +// 96. 不同的二叉搜索树 + + +/* +动态规划: +1、定义dp数组:dp[i] 表示i个节点组成二叉搜索树的种数 +2、初始化:dp[0]=1,dp[1]=1,表示0或1个节点时的种数为1。0个节点的种数为1,用于计算左右子树其中一个为空时不影响乘积结果 +3、状态转移方程: + 1)根据二叉搜索树的特性,左边的节点值 < 中间的节点值 < 右边的节点值 + 2)总共有i个节点时,节点值j作为根节点时,那么左边有j-1个节点,右边有i-j个节点,种数为左边的种数乘以右边的种数,即 dp[i] = dp[j - 1] * dp[i - j]; + 2)由于每个节点都可以作为根节点,所以要累加计算每个节点作为根节点时的种数,即 dp[i] += dp[j - 1] * dp[i - j]; +4、遍历dp数组填表: + 第一个for循环遍历dp数组,从2个节点开始遍历到n个节点 + 第二个for循环遍历每个节点作为根节点时的种数,将种数累加 +5、返回结果:最后一个状态就是结果 + */ +class Solution { + public int numTrees(int n) { + int[] dp = new int[n + 1]; + dp[0] = dp[1] = 1; + for (int i = 2; i <= n; i++) { + for (int j = 1; j <= i; j++) { + dp[i] += dp[j - 1] * dp[i - j]; + } + } + return dp[n]; + } +} + + +/* +递归 + 记忆存储 +定义递归函数: +1、方法功能:入参是节点数,返回对应的种数 +2、终止条件:节点数为0或1时,返回种数为1 +3、返回结果:节点数大于1时,要拿左右的种数相乘,返回乘积种数 +4、递归逻辑: + 1)总共有n个节点时,节点值i作为根节点时,那么左边有i-1个节点,右边有n-i个节点 + 2)由于左右两边的种数同样要计算,因此调用同样的方法获取结果,将左右的种数相乘 + 3)由于每个节点都可以作为根节点,所以要累加计算每个节点作为根节点时的种数 + 4)计算n个节点的种数,存在重复计算,因此使用记忆存储,存在则直接返回结果 + */ +class Solution { + Map memo = new HashMap<>(); + + public int numTrees(int n) { + if (n == 0 || n == 1) { + return 1; + } + if (memo.containsKey(n)) { + return memo.get(n); + } + int count = 0; + for (int i = 1; i <= n; i++) { + int leftNum = numTrees(i - 1); + int rightNum = numTrees(n - i); + count += leftNum * rightNum; + } + memo.put(n, count); + return count; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0098.java b/leetcode_Java/Solution0098.java new file mode 100644 index 0000000..8a9a2be --- /dev/null +++ b/leetcode_Java/Solution0098.java @@ -0,0 +1,140 @@ +// 98. 验证二叉搜索树 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +有效二叉搜索树定义如下: +1、节点的左子树只包含 小于 当前节点的数。 +2、节点的右子树只包含 大于 当前节点的数。 +3、所有左子树和右子树自身必须也是二叉搜索树。 + */ + + +/* +中序遍历: +1、方法功能:入参是一个节点,判断当前节点是否比前一节点大,不是则返回false,是则返回true +2、终止条件:节点为空时返回true,才能继续遍历不为空的节点 +3、单节点处理过程和返回结果:判断当前节点是否比前一节点大,不是则返回false,是则保存当前节点值,并返回true +4、递归调用:左右节点需要同样的操作,因此调用同样的方法处理,获取结果 +5、递归顺序:中序遍历,根节点的处理依赖左节点的值,右节点的处理依赖根节点的值。需要中序遍历有序地保存前一节点值,给下一节点判断 +6、使用递归调用结果和返回结果: + 1)左节点不满足则返回false,满足则继续判断根节点; + 2)根节点不满足则返回false,满足则继续判断右节点; + 3)右节点不满足则返回false,满足则返回true,即直接返回右节点处理结果即可 + */ +class Solution { + private long pre = Long.MIN_VALUE; + + public boolean isValidBST(TreeNode root) { + if (root == null) { + return true; + } + if (!isValidBST(root.left)) { + return false; + } + if (root.val <= pre) { + return false; + } + pre = root.val; + return isValidBST(root.right); + } +} + + +/* +递归: +1、方法功能:入参是节点、最小值、最大值,判断节点值是否有效,即是否满足 min < val < max,有效返回true,无效返回false +2、终止条件:节点为空返回true +3、单节点处理过程和返回结果:判断节点值是否有效,即是否满足 min < val < max,有效效返回true,无效返回false +4、递归调用:左右节点需要同样的操作,因此调用同样的方法处理,获取结果 +5、递归顺序:前序遍历,左右节点的处理依赖根节点的值,所以要先处理根节点,再处理左右节点 +6、使用递归调用结果和返回结果:左右节点同时有效则返回true,否则返回false + */ +class Solution { + public boolean isValidBST(TreeNode root) { + return isValid(root, null, null); + } + + private boolean isValid(TreeNode root, TreeNode min, TreeNode max) { + if (root == null) { + return true; + } + if (min != null && root.val <= min.val) { + return false; + } + if (max != null && root.val >= max.val) { + return false; + } + return isValid(root.left, min, root) && isValid(root.right, root, max); + } +} + + +/* +“94. 二叉树的中序遍历”,中序遍历存入列表,再遍历判断是否升序 + */ +class Solution { + public List list = new ArrayList<>(); + + public boolean isValidBST(TreeNode root) { + inorderTraversal(root); + for (int i = 1; i < list.size(); i++) { + if (list.get(i) <= list.get(i - 1)) { + return false; + } + } + return true; + } + + public List inorderTraversal(TreeNode root) { + if (root == null) { + return list; + } + inorderTraversal(root.left); + list.add(root.val); + inorderTraversal(root.right); + return list; + } +} + + +/* +迭代:“94. 二叉树的中序遍历”,中序遍历过程更新保存前一节点值,当前节点值小于等于前一节点值,则无效,否则有效 + */ +class Solution { + public boolean isValidBST(TreeNode root) { + long pre = Long.MIN_VALUE; + Deque stack = new ArrayDeque<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + if (cur != null) { + stack.push(cur); + cur = cur.left; + } else { + cur = stack.pop(); + if (cur.val <= pre) { + return false; + } + pre = cur.val; + cur = cur.right; + } + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0101.java b/leetcode_Java/Solution0101.java new file mode 100644 index 0000000..ace2c1e --- /dev/null +++ b/leetcode_Java/Solution0101.java @@ -0,0 +1,102 @@ +// 101. 对称二叉树 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、方法定义: + 1)由于要判断两个节点对应的左右子节点值是否相同,原方法入参只有一个节点不够用,需要再定义一个有两个节点作为入参的方法 + 2)不管是原方法还是新方法,其返回类型和返回结果都跟题目要求的返回类型和返回结果一致 +2、方法功能: + 1)入参是两个节点,判断两个节点是否相同 + 2)节点都为空、节点都不为空且值相等则返回true;节点只有一个不为空、节点都不为空但值不相等则返回false +3、递归逻辑: + 1)两个节点的左右子节点同样可以调用这个方法,判断节点是否相同,得到true或false的结果 + 2)当前层节点对称,才会继续递归下一层 + 3)每一层,每两个节点作为入参,调用方法,都得到了true或false的结果 + 4)上一层使用下一层的结果,将下一层多个结果进行与运算,得到下一层的节点是否对称 +======================================================================================================= +新注释模板,递归 +1、方法功能:判断对称需要两个节点参与,入参是两个节点,判断两个节点值是否相同,相同返回true,不同返回false +2、终止条件:两个节点都为空时,返回true +3、两个节点处理过程和返回结果:判断两个节点值是否相同,相同返回true,不同返回false +4、递归调用:两个节点对应的两对左右节点值同样需要判断是否相同,因此调用同样的方法处理,获取结果 +5、递归顺序:前序遍历,先判断当前两个节点值是否相同,不同则结束返回false,相同则继续判断两对左右节点值是否相同 +6、使用递归调用结果和返回结果:两对左右节点值都相同则返回true,否则返回false + 1 + / \ + 2 2 + / \ / \ + 3 4 4 3 +* */ +class Solution { + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + return isSameTree(root.left, root.right); + } + + public boolean isSameTree(TreeNode p, TreeNode q) { + if (p == null && q == null) { + return true; + } + if (p != null && q != null && p.val == q.val) { + return isSameTree(p.left, q.right) && isSameTree(p.right, q.left); + } + return false; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:队列按序存放节点 +* 2、队列初始化:将根节点的左右节点存入队列 +* 3、迭代逻辑: +* 1)遍历队列,弹出两个节点,比较是否相同 +* 2)不相同则返回false。都为空、都不为空且值相等,则存入两个节点对应的下一层的四个左右子节点节点 +* 3)最终节点都存入了队列,且弹出判断都两两相同,则返回true +* */ +class Solution { + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + Queue queue = new LinkedList<>(); + queue.offer(root.left); + queue.offer(root.right); + while (!queue.isEmpty()) { + TreeNode p = queue.poll(); + TreeNode q = queue.poll(); + if (p == null && q == null) { + continue; + } + if (p != null && q != null && p.val == q.val) { + queue.offer(p.left); + queue.offer(q.right); + queue.offer(p.right); + queue.offer(q.left); + continue; + } + return false; + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0102.java b/leetcode_Java/Solution0102.java new file mode 100644 index 0000000..4d91b5e --- /dev/null +++ b/leetcode_Java/Solution0102.java @@ -0,0 +1,162 @@ +// 102. 二叉树的层序遍历 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +* 迭代思路: +* 1、定义数据结构:二维列表存放结果;队列按序存放每层节点;临时子列表存放每层节点值 +* 2、辅助标记:整型变量标记每层在队列的节点个数,以便维护二维列表 +* 3、实现逻辑:遍历当层节点,节点值存入子列表,下一层节点从左到右按序存入队列,循环遍历队列节点 +* 4、队列:先进先出,尾部存入,头部移除 +* */ +class Solution { + public List> levelOrder(TreeNode root) { + List> list = new ArrayList<>(); + if (root == null) { + return list; + } + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int count = queue.size(); + List sonList = new ArrayList<>(); + while (count > 0) { + root = queue.remove(); + sonList.add(root.val); + if (root.left != null) { + queue.add(root.left); + } + if (root.right != null) { + queue.add(root.right); + } + count--; + } + list.add(sonList); + } + return list; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:二维列表存放结果;队列按序存放每层节点;临时子列表存放每层节点值 +* 2、辅助标记:在队列中,每一层的尾部添加哨兵,标记该层的结束位置 +* 2、实现逻辑: +* 1)先将根节点和哨兵加入队列,初始化第一层 +* 2)通过对象类型区分节点与哨兵。 +* 如果是节点,则将节点值存入子列表,将左右节点存入队列。 +* 如果是哨兵,表示当前层结束,将子列表存入结果列表。如果队列还有元素即还有下一层,则创建新的子列表存放下一层节点值,在队列尾部添加哨兵,标记下一层的结束位置 +* */ +class Solution { + public List> levelOrder(TreeNode root) { + List> list = new ArrayList<>(); + if (root == null) { + return list; + } + List sonList = new ArrayList(); + Queue queue = new LinkedList<>(); + queue.add(root); + queue.add(0); + while (!queue.isEmpty()) { + Object obj = queue.remove(); + if (obj instanceof TreeNode) { + TreeNode node = (TreeNode) obj; + sonList.add(node.val); + if (node.left != null) { + queue.add(node.left); + } + if (node.right != null) { + queue.add(node.right); + } + } else { + list.add(sonList); + if (!queue.isEmpty()) { + sonList = new ArrayList(); + queue.add(0); + } + } + } + return list; + } +} + + +/* +递归思路: +1、定义数据结构:成员变量:列表存放递归结果 + 局部变量:子列表存放每层节点值 +2、辅助标记:整型变量标记 层的深度 对应 子列表的索引 +3、递归逻辑: + 1)前序遍历,深度优先搜索,每个节点都会遍历到,每层节点最终都是从左到右按序访问 + 2)记录节点所在层的深度,每到新的一层就创建一个新的子列表,层的深度对应子列表的索引,节点值层序存放 +======================================================================================== +新注释模板,递归 +1、方法功能:入参是节点、层数,将节点值加入该层的子列表中。层数参数逐层累加,标记当前所在层,方便对应获取当前层的子列表 +2、终止条件:节点为空时,结束 +3、一个节点处理过程和返回结果:当该层的子列表未创建时,则创建子列表加入全局列表中。将节点值加入该层的子列表中 +4、递归调用:左右节点同样需要加入对应层的子列表中,因此调用同样的方法处理 +5、递归顺序:前序遍历,要求层序遍历,所以要先处理根节点,再处理左右节点 +6、使用递归调用结果和返回结果:不用接收返回结果,将节点值加入子列表即可 +* */ +class Solution { + List> list = new ArrayList<>(); + + public List> levelOrder(TreeNode root) { + dfs(root, 1); + return list; + } + + public void dfs(TreeNode root, int layer) { + if (root == null) { + return; + } + if (list.size() < layer) { + list.add(new ArrayList<>()); + } + list.get(layer - 1).add(root.val); + dfs(root.left, layer + 1); + dfs(root.right, layer + 1); + } +} + + +/* +上一解法递归函数返回类型为void,但也可以顺便利用返回结果,不接收处理,目的是最后把结果列表返回了 + */ +class Solution { + List> list = new ArrayList<>(); + + public List> levelOrder(TreeNode root) { + return dfs(root, 1); + } + + public void dfs(TreeNode root, int layer) { + if (root == null) { + return list; + } + if (list.size() < layer) { + list.add(new ArrayList<>()); + } + list.get(layer - 1).add(root.val); + dfs(root.left, layer + 1); + dfs(root.right, layer + 1); + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0103.java b/leetcode_Java/Solution0103.java new file mode 100644 index 0000000..73ff061 --- /dev/null +++ b/leetcode_Java/Solution0103.java @@ -0,0 +1,84 @@ +// 103. 二叉树的锯齿形层序遍历 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +“102.二叉树的层序遍历”,奇数层正序插入节点值,偶数层逆序插入节点值 + */ +class Solution { + List> list = new ArrayList<>(); + + public List> zigzagLevelOrder(TreeNode root) { + dfs(root, 1); + return list; + } + + public void dfs(TreeNode root, int layer) { + if (root == null) { + return; + } + if (list.size() < layer) { + list.add(new ArrayList<>()); + } + if (layer % 2 == 1) { + list.get(layer - 1).add(root.val); + } else { + list.get(layer - 1).add(0, root.val); + } + dfs(root.left, layer + 1); + dfs(root.right, layer + 1); + } +} + + +/* +“102.二叉树的层序遍历”,加上是否反转标记,奇数层不变,偶数层反转子数组 + */ +class Solution { + public List> zigzagLevelOrder(TreeNode root) { + List> list = new ArrayList<>(); + if (root == null) { + return list; + } + Queue queue = new LinkedList<>(); + queue.add(root); + boolean flag = false; + while (!queue.isEmpty()) { + int count = queue.size(); + List sonList = new ArrayList<>(); + while (count > 0) { + TreeNode node = queue.remove(); + sonList.add(node.val); + if (node.left != null) { + queue.add(node.left); + } + if (node.right != null) { + queue.add(node.right); + } + count--; + } + if (flag) { + Collections.reverse(sonList); + } + list.add(sonList); + flag = !flag; + } + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0104.java b/leetcode_Java/Solution0104.java new file mode 100644 index 0000000..233cc23 --- /dev/null +++ b/leetcode_Java/Solution0104.java @@ -0,0 +1,77 @@ +// 104. 二叉树的最大深度 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、方法功能:入参是一个节点,节点为空返回0,节点不为空返回1 +2、递归逻辑: + 1)左右节点同样可以调用这个方法,得到0或1的结果 + 2)每一层,每个节点,调用方法,都得到了0或1的结果 + 3)上一层使用下一层的结果,取下一层左右节点结果的最大值,累加到当前层,从而得到二叉树的最大深度 +================================================================================== +计算深度递归函数 +1、方法功能:入参是一个节点,返回节点的深度 +2、终止条件:节点为空时返回0 +3、一个节点处理过程和返回结果:节点不为空时返回1 +4、递归调用:左右节点同样需要计算深度,因此调用同样的方法处理,获取结果 +5、递归顺序:后序遍历,当前节点的深度计算依赖左右节点的深度 +6、使用递归调用结果和返回结果:当前节点的深度 = 1 + max(左节点深度, 右节点深度) +* */ +class Solution { + public int maxDepth(TreeNode root) { + if (root == null) { + return 0; + } + return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:队列存放每一层的节点 +* 2、定义局部变量:deep记录深度;count记录每层节点个数,以便标记队列节点每层结束位置 +* 2、实现逻辑:层序遍历,遍历当前层节点时,把下一层节点存入队列,每一层遍历结束后,深度加1,最终得到最大深度 +* */ +class Solution { + public int maxDepth(TreeNode root) { + if (root == null) { + return 0; + } + int deep = 0; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + int count = queue.size(); + while (count > 0) { + root = queue.poll(); + if (root.left != null) { + queue.offer(root.left); + } + if (root.right != null) { + queue.offer(root.right); + } + count--; + } + deep++; + } + return deep; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0105.java b/leetcode_Java/Solution0105.java new file mode 100644 index 0000000..4eb23f3 --- /dev/null +++ b/leetcode_Java/Solution0105.java @@ -0,0 +1,142 @@ +// 105. 从前序与中序遍历序列构造二叉树 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、方法功能:入参是两个数组,两个数组都为空时返回空,不为空时创建、返回根节点 +2、递归逻辑: + 1)根据前、中序数组的特点,拆分出左子树和右子树两部分数组 + 2)左右子树的数组同样可以调用这个方法,得到左右子树的根节点 + 3)上一层使用下一层的结果,取下一层左子树的根节点作为当前层的左子节点,取下一层右子树的根节点作为当前层的右子节点 +=============================================================================================== +构造节点递归函数 +1、方法功能:入参是前序、中序数组,构造根节点,并返回根节点 +2、终止条件:两个数组都为空时,返回空 +3、一个节点处理过程和返回结果:获取前序数组首元素,构造根节点,返回根节点 +4、递归调用:左右节点同样需要构造,因此调用同样的方法递归处理,获取结果 +5、递归顺序:前序遍历,要先构造根节点,再去构造左右节点 +6、使用递归调用结果和返回结果:获取左右节点后,将其与根节点连接,然后返回根节点 + */ +class Solution { + public TreeNode buildTree(int[] preorder, int[] inorder) { + if (preorder.length == 0 && inorder.length == 0) { + return null; + } + TreeNode root = new TreeNode(preorder[0]); + int index = Arrays.asList(Arrays.stream(inorder).boxed().toArray(Integer[]::new)).indexOf(preorder[0]); + root.left = buildTree(Arrays.copyOfRange(preorder, 1, index + 1), Arrays.copyOfRange(inorder, 0, index)); + root.right = buildTree(Arrays.copyOfRange(preorder, index + 1, preorder.length), Arrays.copyOfRange(inorder, index + 1, inorder.length)); + return root; + } +} + + +/* +递归思路: +1、数据结构: + 1)使用Map存放中序数组的元素和索引,方便直接获取索引,避免了重复遍历获取 + 2)使用指针表示数组的开始和结束位置,避免了数组的拆分和拷贝,节省额外空间。注意两个指针指向的数组范围是包括左边界,不包括右边界 +2、递归逻辑: + 1)原方法入参不够用,创建一个新的方法作为递归方法 + 2)方法的功能:终止条件,当数组为空时,前序起始、结束指针位置相同,返回空;不为空时创建、返回根节点 + 3)通过指针划分左右子树的数组范围,调用同个方法得到左右子树的根节点 + 4)上一层使用下一层的结果,取下一层左子树的根节点作为当前层的左子节点,取下一层右子树的根节点作为当前层的右子节点 +============================================================================================================ +新注释模板,递归 +构造节点递归函数 +1、方法功能:入参是两个数组、对应的开始和结束边界 +2、终止条件:开始边界等于结束边界,说明数组为空,返回空 +3、一个节点处理过程和返回结果:获取前序数组首元素,构造根节点,返回根节点 +4、递归调用:左右节点同样需要构造,因此调用同样的方法递归处理,获取结果 +5、递归顺序:前序遍历,要先构造根节点,再去构造左右节点 +6、使用递归调用结果和返回结果:获取左右节点后,将其与根节点连接,然后返回根节点 + */ +class Solution { + Map map = new HashMap<>(); + + public TreeNode buildTree(int[] preorder, int[] inorder) { + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); + } + return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length); + } + + public TreeNode buildTreeHelper(int[] preorder, int pStart, int pEnd, int[] inorder, int iStart, int iEnd) { + if (pStart == pEnd) { + return null; + } + int rootVal = preorder[pStart]; + TreeNode root = new TreeNode(rootVal); + int iRootIndex = map.get(rootVal); + int leftNum = iRootIndex - iStart; + root.left = buildTreeHelper(preorder, pStart + 1, pStart + leftNum + 1, inorder, iStart, iRootIndex); + root.right = buildTreeHelper(preorder, pStart + leftNum + 1, pEnd, inorder, iRootIndex + 1, iEnd); + return root; + } +} + + +/* +迭代: +1、用一个栈和一个指针辅助进行二叉树的构造。初始时栈中存放了根节点(前序遍历的第一个节点),指针指向中序遍历的第一个节点 +2、依次枚举前序遍历中除了第一个节点以外的每个节点 + 1)如果 index 恰好指向栈顶节点,那么不断地弹出栈顶节点并向右移动 index,并将当前节点作为最后一个弹出的节点的右儿子 + 2)如果 index 和栈顶节点不同,将当前节点作为栈顶节点的左儿子 + 3)无论是哪一种情况,最后都将当前的节点入栈 + +preorder = [3, 9, 8, 5, 4, 10, 20, 15, 7] +inorder = [4, 5, 8, 10, 9, 3, 15, 20, 7] + 3 + / \ + 9 20 + / / \ + 8 15 7 + / \ + 5 10 + / +4 + */ +class Solution { + public TreeNode buildTree(int[] preorder, int[] inorder) { + if (preorder == null || preorder.length == 0) { + return null; + } + TreeNode root = new TreeNode(preorder[0]); + Deque stack = new ArrayDeque<>(); + stack.push(root); + int inorderIndex = 0; + for (int i = 1; i < preorder.length; i++) { + int preorderVal = preorder[i]; + TreeNode node = stack.peek(); + if (node.val != inorder[inorderIndex]) { + node.left = new TreeNode(preorderVal); + stack.push(node.left); + } else { + while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) { + node = stack.pop(); + inorderIndex++; + } + node.right = new TreeNode(preorderVal); + stack.push(node.right); + } + } + return root; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0110.java b/leetcode_Java/Solution0110.java new file mode 100644 index 0000000..2def0de --- /dev/null +++ b/leetcode_Java/Solution0110.java @@ -0,0 +1,125 @@ +// 110. 平衡二叉树 +// 解法类似“543. 二叉树的直径” + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +剑指offer 39.平衡二叉树 +1、本题需要两个递归方法,一个是递归计算每个节点的深度,一个是递归判断每个节点是否平衡。自顶向下 +2、递归计算节点深度 + 1)方法功能:入参是一个节点,返回该节点的深度 + 2)终止条件:节点为空时返回0 + 3)递归逻辑:左右节点同样需要计算深度,因此调用同样的方法 + 4)返回值:节点的深度 = 1 + max(左节点深度, 右节点深度) +3、递归判断每个节点是否平衡 + 1)方法功能:入参是一个节点,返回该节点的左右子树是否平衡 + 2)终止条件:节点为空时返回true + 3)递归逻辑:调用计算深度的方法得到左右节点的深度,计算高度差是否不超过1,是则平衡返回true,否则不平衡返回false。左右节点同样需要判断是否平衡,因此调用同样的方法 + 4)返回值:节点为根的树是否平衡 且 左节点为根的树是否平衡 且 右节点为根的树是否平衡 + */ +class Solution { + public boolean isBalanced(TreeNode root) { + if (root == null) { + return true; + } + return Math.abs(treeDepth(root.left) - treeDepth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right); + } + + private int treeDepth(TreeNode root) { + if (root == null) { + return 0; + } + return 1 + Math.max(treeDepth(root.left), treeDepth(root.right)); + } +} + + +/* +递归 + 记忆存储:自顶向下 +1、计算深度递归函数 + 1)方法功能:入参是一个节点,返回节点的深度 + 2)终止条件:节点为空时返回0 + 3)一个节点处理过程和返回结果:节点不为空时返回1 + 4)递归调用:左右节点同样需要计算深度,因此调用同样的方法处理,获取结果 + 5)递归顺序:后序遍历,当前节点的深度计算依赖左右节点的深度 + 6)使用递归调用结果和返回结果:当前节点的深度 = 1 + max(左节点深度, 右节点深度) + 7)递归结果记忆存储:判断节点是否平衡时,会重复计算节点的深度,使用哈希表存储节点对应的深度 {节点:深度},重复调用时可直接获取返回 +2、判断节点是否平衡 + 1)方法功能:入参是一个节点,返回该节点是否平衡 + 2)终止条件:节点为空返回true + 3)一个节点处理过程和返回结果:abs(左节点深度 - 右节点深度) <= 1 时,则节点平衡返回true,否则返回false + 4)递归调用:左右节点同样需要判断是否平衡,因此调用同样的方法处理,获取结果 + 5)递归顺序:前序遍历,当前节点是否平衡不依赖左右节点是否,三者顺序可随意。可以先判断根节点是否平衡,然后判断左节点是否平衡,最后判断右节点是否平衡 + 6)使用递归调用结果和返回结果:二叉树是否平衡 = 根节点是否平衡 && 左节点是否平衡 && 右节点是否平衡 + */ +class Solution { + Map map = new HashMap<>(); + + public boolean isBalanced(TreeNode root) { + if (root == null) { + return true; + } + return Math.abs(treeDepth(root.left) - treeDepth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right); + } + + private int treeDepth(TreeNode root) { + if (root == null) { + return 0; + } + if (map.get(root) != null) { + return map.get(root); + } + int depth = 1 + Math.max(treeDepth(root.left), treeDepth(root.right)); + map.put(root, depth); + return depth; + } +} + + +/* +递归 + 平衡标志:自底向上 +计算节点深度递归函数:计算深度的同时,利用深度判断是否平衡 +1、方法功能:入参是一个节点,返回节点的深度 +2、终止条件:节点为空时返回0 +3、一个节点处理过程和返回结果:节点不为空时返回1 +4、递归调用:左右节点同样需要计算深度,因此调用同样的方法处理,获取结果 +5、递归顺序:后序遍历,当前节点的深度计算依赖左右节点的深度 +6、使用递归调用结果和返回结果 + 1)当前节点的深度 = 1 + max(左节点深度, 右节点深度) + 2)平衡标志flag为true 且 左右节点深度差大于1,则二叉树不平衡,更新成员变量flag为false + */ +class Solution { + boolean flag = true; + + public boolean isBalanced(TreeNode root) { + depth(root); + return flag; + } + + public int depth(TreeNode root) { + if (root == null) { + return 0; + } + int left = depth(root.left); + int right = depth(root.right); + if (flag && Math.abs(left - right) > 1) { + flag = false; + } + return 1 + Math.max(left, right); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0112.java b/leetcode_Java/Solution0112.java new file mode 100644 index 0000000..a08f83d --- /dev/null +++ b/leetcode_Java/Solution0112.java @@ -0,0 +1,84 @@ +// 112. 路径总和 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归: +1、方法功能:入参是一个节点,返回该节点值是否等于目标和 +2、终止条件:节点为空时返回false +3、返回结果:节点不为空时,如果是叶子结点且节点值等于目标和,则返回true +4、递归逻辑: + 1)没到达叶子结点前,左右节点同样要计算获取结果,再拿结果处理,其中一个为true则返回true + 2)自顶向下累减传递目标和,到叶子结点后,自底向上返回处理结果 +=========================================================================== +新注释模板,递归 +1、方法功能:入参是节点、目标值,判断节点值是否等于目标值,是则返回true,否则返回false +2、终止条件:节点为空时,返回false +3、一个节点处理过程和返回结果:到达叶子结点才作判断,即 左右节点为空 且 节点值等于目标值,是则返回true,否则返回false +4、递归调用:左右节点同样需要判断是否等于目标值,因此调用同样的方法递归处理,获取结果。递归参数目标值累减,减去当前节点值 +5、递归顺序:前序遍历,要先判断根节点是否满足,满足则结束返回true,不满足再继续判断左右节点 +6、使用递归调用结果和返回结果:左节点满足 或 右节点满足,那么就存在路径和为目标值,返回true,否则返回false + */ +class Solution { + public boolean hasPathSum(TreeNode root, int targetSum) { + if (root == null) { + return false; + } + if (root.left == null && root.right == null && root.val == targetSum) { + return true; + } + targetSum -= root.val; + return hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum); + } +} + + +/* +广度优先搜索: +1、层序遍历节点,利用两个队列分别保存 节点 和 到达节点时的路径和 +2、当节点是叶子节点时,判断路径和等于目标和则返回true,否则将左右节点与其对应的路径和加入队列中,继续循环处理 +3、遍历结束后没有找到目标和则返回false + */ +class Solution { + public boolean hasPathSum(TreeNode root, int targetSum) { + if (root == null) { + return false; + } + Queue nodeQueue = new LinkedList<>(); + Queue sumQueue = new LinkedList<>(); + nodeQueue.add(root); + sumQueue.add(root.val); + while (!nodeQueue.isEmpty()) { + TreeNode node = nodeQueue.poll(); + Integer sum = sumQueue.poll(); + if (node.left == null && node.right == null && sum == targetSum) { + return true; + } + if (node.left != null) { + nodeQueue.add(node.left); + sumQueue.add(sum + node.left.val); + } + if (node.right != null) { + nodeQueue.add(node.right); + sumQueue.add(sum + node.right.val); + } + } + return false; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0113.java b/leetcode_Java/Solution0113.java new file mode 100644 index 0000000..2ee08b8 --- /dev/null +++ b/leetcode_Java/Solution0113.java @@ -0,0 +1,111 @@ +// 113. 路径总和 II + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归,回溯: +1、成员变量 res 存放结果路径,path 存放搜索过程路径 +2、定义递归函数 + 1)方法功能:入参是节点、目标和,将节点值加入path路径列表,当节点为叶子结点 且 节点值等于目标和,则将路径加入res结果列表。处理结果加入列表即可,不需要返回 + 2)终止条件:节点为空时,结束 + 3)递归逻辑:左右节点同样需要加入路径、判断目标和,因此调用同样的方法实现递归处理。当前节点递归处理完成后需要从路径中移除节点值,即回溯,不影响其他路径的递归处理 +======================================================================================================================================= +新注释模板,递归 +1、方法功能:入参是节点、目标和,将节点值加入path路径列表,当节点为叶子结点 且 节点值等于目标和,则将路径加入res结果列表 +2、终止条件:节点为空时,结束 +3、一个节点处理过程和返回结果:将节点值加入path路径列表,当节点为叶子结点 且 节点值等于目标和,则将路径加入res结果列表 +4、递归调用:左右节点同样需要加入路径、判断目标和,因此调用同样的方法递归处理。递归参数目标和累减,减去当前节点值。 +5、递归顺序:前序遍历,路径顺序从根节点到叶结点,所以要先处理根节点,再处理左右节点 + 当前节点递归处理完成后需要从路径中移除节点值,即回溯,不影响其他路径的递归处理 +6、使用递归调用结果和返回结果:没有返回值需要接收,最后返回res结果列表即可 + */ +class Solution { + private List> res = new ArrayList<>(); + private List path = new ArrayList<>(); + + public List> pathSum(TreeNode root, int targetSum) { + dfs(root, targetSum); + return res; + } + + private void dfs(TreeNode root, int targetSum) { + if (root == null) { + return; + } + path.add(root.val); + if (root.left == null && root.right == null && root.val == targetSum) { + res.add(new ArrayList<>(path)); + } + targetSum -= root.val; + dfs(root.left, targetSum); + dfs(root.right, targetSum); + path.remove(path.size() - 1); + } +} + + +/* +广度优先搜索: +1、成员变量 res 存放结果路径;map存放 {节点:父节点} 关系,用于根据叶子结点找出整条路径 +2、层序遍历节点,利用两个队列分别保存 节点 和 到达节点时的路径和 +3、当节点是叶子节点时,判断路径和等于目标和则获取路径加入res结果列表中。 + 否则将左右节点与其对应的路径和加入队列中,并且保存左右节点与父节点的关系到map中,然后继续循环处理 +4、最后返回res结果列表 + */ +class Solution { + private List> res = new ArrayList<>(); + private Map map = new HashMap<>(); + + public List> pathSum(TreeNode root, int targetSum) { + if (root == null) { + return res; + } + Queue nodeQueue = new LinkedList<>(); + Queue sumQueue = new LinkedList<>(); + nodeQueue.add(root); + sumQueue.add(root.val); + while (!nodeQueue.isEmpty()) { + TreeNode node = nodeQueue.poll(); + Integer sum = sumQueue.poll(); + if (node.left == null && node.right == null && sum == targetSum) { + getPath(node); + } + if (node.left != null) { + nodeQueue.add(node.left); + sumQueue.add(sum + node.left.val); + map.put(node.left, node); + } + if (node.right != null) { + nodeQueue.add(node.right); + sumQueue.add(sum + node.right.val); + map.put(node.right, node); + } + } + return res; + } + + private void getPath(TreeNode node) { + List path = new ArrayList<>(); + while (node != null) { + path.add(0, node.val); + node = map.get(node); + } + res.add(new ArrayList<>(path)); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0114.java b/leetcode_Java/Solution0114.java new file mode 100644 index 0000000..5ce2799 --- /dev/null +++ b/leetcode_Java/Solution0114.java @@ -0,0 +1,130 @@ +// 114. 二叉树展开为链表 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +* 迭代思路: +* 1、简单理解:把左子树塞到根节点和右节点中间,每个节点都要做同样的操作 +* 2、简单情况分析: +* 1)根节点为空:直接返回列表 +* 2)只有根节点:将根节点的值存入列表,返回列表 +* 3)有根节点和左节点:将左节点移到右节点的位置,遍历右节点将值存入列表,返回列表 +* 4)有根节点和右节点:不用移动,遍历右节点将值存入列表,返回列表 +* 5)有根节点、左节点、右节点:将左节点移到根节点和右节点中间,遍历右节点将值存入列表,返回列表 +* 3、节点连接步骤: +* 1)前序遍历是中左右,即根节点→左子树→右子树 +* 2)左子树遍历的最后一个节点是 左子树的最后一个右子节点,因此要将其连接到根节点的右节点上 +* 3)根节点的右指针要指向左节点,左指针指向空,从而形成中左右的链表 +* 4、遍历逻辑: +* 1)根指针的移动代表着前序遍历的顺序,循环遍历条件是根指针不为空 +* 2)如果根节点的左节点不为空,则进行节点连接步骤;如果为空,则将节点值存入列表 +* 3)根节点处理完后,根指针指向右节点,准备下一轮判断 +* 5、“144.二叉树的前序遍历”展开为链表的解法 +* */ +class Solution { + public List flatten(TreeNode root) { + List list = new ArrayList<>(); + while (root != null) { + if (root.left != null) { + TreeNode pre = root.left; + while (pre.right != null) { + pre = pre.right; + } + pre.right = root.right; + root.right = root.left; + root.left = null; + } + list.add(root.val); + root = root.right; + } + return list; + } +} + + +/* +* 迭代思路:与上个解法相同。用队列/栈存储下一个要遍历的节点,替代了遍历指针,缺点是使用了多余的空间 +* */ +class Solution { + public List flatten(TreeNode root) { + List list = new ArrayList<>(); + if (root == null) { + return list; + } + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + root = queue.poll(); + if (root.left != null) { + TreeNode pre = root.left; + while (pre.right != null) { + pre = pre.right; + } + pre.right = root.right; + root.right = root.left; + root.left = null; + } + list.add(root.val); + if (root.right != null) { + queue.offer(root.right); + } + } + return list; + } +} + + +// 方法返回空写法。迭代 +class Solution { + public void flatten(TreeNode root) { + while (root != null) { + if (root.left != null) { + TreeNode pre = root.left; + while (pre.right != null) { + pre = pre.right; + } + pre.right = root.right; + root.right = root.left; + root.left = null; + } + root = root.right; + } + } +} + + +// 递归 +class Solution { + public void flatten(TreeNode root) { + if (root == null) { + return; + } + if (root.left != null) { + TreeNode pre = root.left; + while (pre.right != null) { + pre = pre.right; + } + pre.right = root.right; + root.right = root.left; + root.left = null; + } + flatten(root.left); + flatten(root.right); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0115.java b/leetcode_Java/Solution0115.java new file mode 100644 index 0000000..dacfd5f --- /dev/null +++ b/leetcode_Java/Solution0115.java @@ -0,0 +1,67 @@ +// 115. 不同的子序列 + + +/* +动态规划: +1、题目简化:求s的子序列中t出现的个数 +1、定义dp数组:dp[i][j] 表示 s前i个字符 中出现 t前j个字符 的个数 +2、初始化: + 1)二维dp数组扩容:增加空字符串这一最小规模的情况,方便直观初始化 + 2)dp[i][0] = 1 表示 s前i个字符 中出现 t前0个字符 的个数为1,即空字符串是任何字符串的子集 + dp[0][j] = 0 表示 s前0个字符 中出现 t前j个字符 的个数为0,即空字符串不会出现任何字符串 + dp[0][0] = 1 表示 s前i个字符 中出现 t前0个字符 的个数为1,即空字符串是空字符串的子集 +3、状态转移方程: + 1)s中不同索引位置的字符组合,代表不同的子序列 + 2)如果s[i] == s[j],那么s有两种方式可以匹配t + 第一种是用s[i]匹配掉t[j],那么出现个数为 s前i-1个字符中出现t前j-1个字符的个数,即 dp[i - 1][j - 1] + 第二种是不用s[i]匹配t[j],那么出现个数为 s前i-1个字符中出现t前j个字符的个数,即 dp[i - 1][j] + 所以 dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; + 3)如果s[i] != s[j],那么s只能不用s[i]匹配t[j],那么出现个数为 s前i-1个字符中出现t前j个字符的个数,即 dp[i - 1][j] + 所以 dp[i][j] = dp[i - 1][j]; +4、遍历dp数组填表: + 1)两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的出现个数 + 2)遍历顺序决定了哪些位置是计算过的、是已知状态,外层遍历字符串s,内层遍历字符串t。 + 从二维数组角度看,遍历顺序是从上到下,从左到右,所以遍历到(i,j)位置时,其左方、上方、左上方状态都已经遍历计算过了。 + 从两个字符串角度看,两个指针分别指向两个字符串,两者遍历顺序都是从左到右,所以遍历到(i,j)位置时,其左边其他位置都遍历计算过了。 + 所以求 dp[i][j] 时,dp[i - 1][j - 1]、dp[i - 1][j] 都是已知状态了 +5、返回结果:最后一个状态就是结果 + +s = "babgbag", t = "bag" +二维数组: + '' b a g +'' 1 0 0 0 +b 1 1 0 0 +a 1 1 1 0 +b 1 2 1 0 +g 1 3 1 1 +b 1 3 4 1 +a 1 3 4 1 +g 1 3 4 5 + +字符串: +s: b a b g b a g + ↑ + i +t: b a g + ↑ + j + */ +class Solution { + public int numDistinct(String s, String t) { + int n = s.length(), m = t.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 0; i <= n; i++) { + dp[i][0] = 1; + } + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (s.charAt(i - 1) == t.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][m]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0121.java b/leetcode_Java/Solution0121.java new file mode 100644 index 0000000..30af1f1 --- /dev/null +++ b/leetcode_Java/Solution0121.java @@ -0,0 +1,97 @@ +// 121. 买卖股票的最佳时机 + + +/* +动态规划: +1、定义dp数组: + dp[i][0] 表示第i天交易结束后不持有股票的最大利润 + dp[i][1] 表示第i天交易结束后持有股票的最大利润 +2、初始化 + dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略 + dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0] +3、状态转移方程 + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); + 第i天不持有股票 前一天不持有股票 前一天持有股票且今天卖出 + dp[i][1] = Math.max(dp[i - 1][1], -prices[i]); // 注意:只能买卖一次,所以买入时的利润为-prices[i] + 第i天持有股票 前一天持有股票 今天买入 +4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:最后一个不持有股票的状态就是结果 + +二维dp数组更新过程 +prices = [7,1,5,3,6,4] +0 -7 +0 -1 +4 -1 +4 -1 +5 -1 +5 -1 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[][] dp = new int[n][2]; + dp[0][0] = 0; + dp[0][1] = -prices[0]; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); + dp[i][1] = Math.max(dp[i - 1][1], -prices[i]); + } + return dp[n - 1][0]; + } +} + + +/* +动态规划思路: +1、定义dp数组:dp[i]表示第i天交易结束后可获得的最大利润(天数从0开始,与索引对应,方便理解) +2、状态转移方程:dp[i] = Math.max(dp[i - 1], prices[i] - minPrice) + 第i-1天可获得的最大利润 第i天卖出可获得的最大利润 +3、初始化:dp[0] = 0,第0天的最大利润为0 +4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:最后一个状态就是结果 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[] dp = new int[n]; + dp[0] = 0; + int minPrice = prices[0]; + for (int i = 1; i < n; i++) { + minPrice = Math.min(minPrice, prices[i]); + dp[i] = Math.max(dp[i - 1], prices[i] - minPrice); + } + return dp[n - 1]; + } +} + + +/* +思路: +1、动态规划维护的dp数组,存放的每个元素只用一次就不需要了,因此可以直接用一个变量来表示利润最大值 +2、遍历列表,计算到当天为止的价格最小值、利润最大值 + */ +class Solution { + public int maxProfit(int[] prices) { + int minPrice = 99999, maxProfit = 0; + for (int price : prices) { + minPrice = Math.min(minPrice, price); + maxProfit = Math.max(maxProfit, price - minPrice); + } + return maxProfit; + } +} + +public class Solution { + public int maxProfit (int[] prices) { + int n = prices.length; + if (n < 2) { + return 0; + } + int minPrice = prices[0], profit = 0; + for (int i = 1; i < n; i++) { + profit = Math.max(profit, prices[i] - minPrice); + minPrice = Math.min(minPrice, prices[i]); + } + return profit; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0122.java b/leetcode_Java/Solution0122.java new file mode 100644 index 0000000..873f566 --- /dev/null +++ b/leetcode_Java/Solution0122.java @@ -0,0 +1,77 @@ +// 122. 买卖股票的最佳时机 II + + +/* +动态规划: +1、定义dp数组: + dp[i][0] 表示第i天交易结束后不持有股票的最大利润 + dp[i][1] 表示第i天交易结束后持有股票的最大利润 +2、初始化 + dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略 + dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0] +3、状态转移方程 + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); + 第i天不持有股票 前一天不持有股票 前一天持有股票且今天卖出 + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); // 注意:可以买卖多次,所以买入时的利润包含之前所得利润,即dp[i - 1][0] - prices[i] + 第i天持有股票 前一天持有股票 前一天不持有股票且今天买入 +4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:最后一个不持有股票的状态就是结果 + +二维dp数组更新过程 +prices = [7,1,5,3,6,4] +0 -7 +0 -1 +4 -1 +4 1 +7 1 +7 3 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[][] dp = new int[n][2]; + dp[0][0] = 0; + dp[0][1] = -prices[0]; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); + } + return dp[n - 1][0]; + } +} + + +/* +动态规划 +1、状态压缩:每一天的状态只与前一天的状态有关,使用变量存储状态 dp[i][0]、dp[i][1] +2、定义状态: + dp0 表示第i天交易结束后不持有股票的最大利润 + dp1 表示第i天交易结束后持有股票的最大利润 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int dp0 = 0, dp1 = -prices[0]; + for (int i = 1; i < n; i++) { + int newDp0 = Math.max(dp0, dp1 + prices[i]); + int newDp1 = Math.max(dp1, dp0 - prices[i]); + dp0 = newDp0; + dp1 = newDp1; + } + return dp0; + } +} + + +/* +贪心:根据股票价格画出折线图,由于交易次数不限,因此把每次上涨差值累加就是最大利润 + */ +class Solution { + public int maxProfit(int[] prices) { + int res = 0; + for (int i = 1; i < prices.length; i++) { + res += Math.max(0, prices[i] - prices[i - 1]); + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0123.java b/leetcode_Java/Solution0123.java new file mode 100644 index 0000000..b452d88 --- /dev/null +++ b/leetcode_Java/Solution0123.java @@ -0,0 +1,140 @@ +// 123. 买卖股票的最佳时机 III + + +/* +与 188.买卖股票的最佳时机IV 解法相同,将k值设置为2即可 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + if (n <= 1) { + return 0; + } + int[][][] dp = new int[n][3][2]; + for (int j = 1; j <= 2; j++) { + dp[0][j][0] = 0; + dp[0][j][1] = -prices[0]; + } + for (int i = 1; i < n; i++) { + for (int j = 1; j <= 2; j++) { + dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]); + dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]); + } + } + return dp[n - 1][2][0]; + } +} + + +/* +状态压缩,去掉天数的维度,交易次数和是否持有股票构成的二维数组变成滚动数组 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + if (n <= 1) { + return 0; + } + int[][] dp = new int[3][2]; + for (int j = 1; j <= 2; j++) { + dp[j][0] = 0; + dp[j][1] = -prices[0]; + } + for (int i = 1; i < n; i++) { + for (int j = 1; j <= 2; j++) { + dp[j][0] = Math.max(dp[j][0], dp[j][1] + prices[i]); + dp[j][1] = Math.max(dp[j][1], dp[j - 1][0] - prices[i]); + } + } + return dp[2][0]; + } +} + + +/* +动态规划,多个一维dp数组,记录多种状态 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[] buy1 = new int[n]; + int[] sell1 = new int[n]; + int[] buy2 = new int[n]; + int[] sell2 = new int[n]; + buy1[0] = -prices[0]; sell1[0] = 0; + buy2[0] = -prices[0]; sell2[0] = 0; + for (int i = 1; i < n; i++) { + buy1[i] = Math.max(buy1[i - 1], -prices[i]); + sell1[i] = Math.max(sell1[i - 1], buy1[i - 1] + prices[i]); + buy2[i] = Math.max(buy2[i - 1], sell1[i - 1] - prices[i]); + sell2[i] = Math.max(sell2[i - 1], buy2[i - 1] + prices[i]); + } + return sell2[n-1]; + } +} + + +/* +动态规划: +1、将多个一维数组写成一个二维数组,行表示天数,四列表示四种状态 +2、定义dp数组: + dp[i][0] 表示第i天交易结束后,进行过第一次买入,获取的最大利润 + dp[i][1] 表示第i天交易结束后,进行过第一次卖出,获取的最大利润 + dp[i][2] 表示第i天交易结束后,进行过第二次买入,获取的最大利润 + dp[i][3] 表示第i天交易结束后,进行过第二次卖出,获取的最大利润 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[][] dp = new int[n][4]; + dp[0][0] = dp[0][2] = -prices[0]; + dp[0][1] = dp[0][3] = 0; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.max(dp[i - 1][0], -prices[i]); + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]); + dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] - prices[i]); + dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] + prices[i]); + } + return dp[n - 1][3]; + } +} + + +/* +动态规划:状态压缩 +1、状态定义:由于最多可以完成两笔交易,因此在任意一天结束之后,会处于以下五个状态中的一种 + 1)没有操作。利润为0,不用记录 + 2)buy1:第一次买入,获取的最大利润 + 3)sell1:第一次卖出,获取的最大利润 + 4)buy2:第二次买入,获取的最大利润 + 5)sell2:第二次卖出,获取的最大利润 +2、状态转移: + buy1 = Math.max(buy1, -prices[i]); // 在第i天没有操作,取前一天buy1的状态。或者在没有操作的前提下以prices[i]的价格买入股票 + sell1 = Math.max(sell1, buy1 + prices[i]); // 在第i天没有操作,取前一天sell1的状态。或者在第一次买入的前提下以prices[i]的价格卖出股票 + buy2 = Math.max(buy2, sell1 - prices[i]); // 在第i天没有操作,取前一天buy2的状态。或者在第一次卖出的前提下以prices[i]的价格买入股票 + sell2 = Math.max(sell2, buy2 + prices[i]); // 在第i天没有操作,取前一天sell2的状态。或者在第二次买入的前提下以prices[i]的价格卖出股票 +3、初始化:第0天的状态 + buy1 = -prices[0] 表示以prices[0]的价格买入股票 + sell1 = 0 表示在同一天买入并且卖出,利润为0 + buy2 = -prices[0] 表示以prices[0]的价格买入股票 + sell2 = 0 表示在同一天买入并且卖出,利润为0 +4、遍历更新状态:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:直接返回sell2 + 1)无交易情况,sell2为0,返回sell2 + 2)只完成交易一次,由于存在同一天买卖的情况,所以sell1可以转移到sell2,返回sell2 + 3)完成两次交易,返回sell2 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int buy1 = -prices[0], sell1 = 0; + int buy2 = -prices[0], sell2 = 0; + for (int i = 1; i < n; i++) { + buy1 = Math.max(buy1, -prices[i]); + sell1 = Math.max(sell1, buy1 + prices[i]); + buy2 = Math.max(buy2, sell1 - prices[i]); + sell2 = Math.max(sell2, buy2 + prices[i]); + } + return sell2; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0124.java b/leetcode_Java/Solution0124.java new file mode 100644 index 0000000..d90f4ce --- /dev/null +++ b/leetcode_Java/Solution0124.java @@ -0,0 +1,58 @@ +// 124. 二叉树中的最大路径和 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归: +1、方法功能:入参是一个节点,返回该节点给父节点的贡献值 +2、终止条件:空节点时返回0 +3、单层递归逻辑: + 1)调用递归方法得到左节点、右节点的贡献值 + 2)计算当前节点为路径根节点时的最大路径和,并更新最大结果。最大路径和 = 根节点值 + 左节点贡献值 + 右节点贡献值 + 3)计算当前节点给父节点的贡献值,若为负数则记为0,并返回贡献值。贡献值 = max(0, 根节点值 + max(左节点贡献值, 右节点贡献值)) +======================================================================================= +新注释模板,递归 +计算贡献值递归函数 +1、方法功能:入参是一个节点,返回该节点的贡献值。贡献值指从该节点出发,向下沿子节点连接的一条路,可获取的最大正收益 +2、终止条件:节点为空时返回0 +3、一个节点处理过程和返回结果:比较并更新最大路径和 max(res, root.val),返回节点的贡献值 max(0, root.val),节点值为负数时贡献值为0 +4、递归调用:左右节点同样需要计算贡献值,因此调用同样的方法递归处理,获取结果 +5、递归顺序:后序遍历,当前节点的贡献值依赖左右节点的贡献值,因此要先计算左右节点的贡献值 +6、使用递归调用结果和返回结果: + 1)当前节点为路径根节点时的最大路径和 = 根节点值 + 左节点贡献值 + 右节点贡献值 + 2)当前节点的贡献值 = max(0, 根节点值 + max(左节点贡献值, 右节点贡献值)) + */ +class Solution { + int res = Integer.MIN_VALUE; + + public int maxPathSum(TreeNode root) { + dfs(root); + return res; + } + + private int dfs(TreeNode root) { + if (root == null) { + return 0; + } + int left = dfs(root.left); + int right = dfs(root.right); + res = Math.max(res, root.val + left + right); + return Math.max(0, root.val + Math.max(left, right)); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0128.java b/leetcode_Java/Solution0128.java new file mode 100644 index 0000000..dfdfffd --- /dev/null +++ b/leetcode_Java/Solution0128.java @@ -0,0 +1,71 @@ +// 128. 最长连续序列 + + +/* +集合: +1、集合存放去重元素 +2、遍历元素 + 1)元素前值存在集合中则跳过,因为当前元素会被前值计算统计出更长的长度,即只从序列的起点开始计算才是最长的 + 2)记录当前元素和当前长度,当元素后值存在集合中,则更新当前元素和当前长度 + 3)比较比记录最长长度 + 4)优化,最长长度大于数组长度一半时,后面的元素就不用判断了 + 因为如果剩余元素不属于这个序列那么长度小于数组长度一半 + 如果属于这个序列,那么序列起点已经计算了,当前就是最长了 + + √:计算长度 x:跳过 + 100 4 200 1 3 2 + √ x √ √ x x + */ +class Solution { + public int longestConsecutive(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + int res = 0; + for (int num : nums) { + if (set.contains(num - 1)) { + continue; + } + int curNum = num; + int curLen = 1; + while (set.contains(curNum + 1)) { + curNum += 1; + curLen += 1; + } + res = Math.max(res, curLen); + if (res > n / 2) { + break; + } + } + return res; + } +} + + +/* +排序: +1、数组排序 +2、遍历统计连续序列长度,记录最长长度 + */ +class Solution { + public int longestConsecutive(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + if (n < 2) { + return n; + } + int res = 1, curLen = 1; + for (int i = 1; i < n; i++) { + if (nums[i] == nums[i - 1] + 1) { + curLen += 1; + res = Math.max(res, curLen); + } else if (nums[i] == nums[i - 1]) { + continue; + } else { + curLen = 1; + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0129.java b/leetcode_Java/Solution0129.java new file mode 100644 index 0000000..774b7f8 --- /dev/null +++ b/leetcode_Java/Solution0129.java @@ -0,0 +1,94 @@ +// 129. 求根节点到叶节点数字之和 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归,深度优先搜索: +1、递归思路:自顶向下计算每个节点“产生的数字”,直到叶子结点才是最终有效的目标数字,再将叶子结点的有效数字 自底向上累加得到所有路径的数字之和 +2、方法功能:入参是当前节点、父节点“产生的数字”,返回当前节点“产生的数字” +3、终止条件:节点为空时返回0 +4、递归逻辑: + 1)计算根节点到达当前节点时“产生的数字” = 父节点“产生的数字” * 10 + 当前节点值 + 2)如果当前节点没有子节点,那么当前节点的数字之和 就是“产生的数字”,直接返回该结果 + 2)如果当前节点有子节点,那么当前节点的数字之和 就是左右节点“产生的数字”的和。左右节点同样需要计算“产生的数字”,因此调用同样的方法,接收到返回值后相加 +=========================================================================================================================== +新注释模板,递归 +1、方法功能:入参是当前节点、父节点“产生的数字”,返回当前节点“产生的数字”。 + 当前节点“产生的数字”依赖前一节点“产生的数字”,所以要创建新方法加参数进行传递构造 +2、终止条件:节点为空时返回0 +3、一个节点处理过程和返回结果:当前节点“产生的数字” = 父节点“产生的数字” * 10 + 当前节点值,返回该结果 +4、递归调用:左右节点同样需要计算“产生的数字”,因此调用同样的方法递归处理,获取结果 +5、递归顺序:前序遍历,左右节点的处理依赖根节点的结果,所以要先处理根节点,再处理左右节点 +6、使用递归调用结果和返回结果:获取左右节点“产生的数字”后,将其相加,得到根节点到叶节点数字之和 + */ +class Solution { + public int sumNumbers(TreeNode root) { + return dfs(root, 0); + } + + private int dfs(TreeNode root, int preSum) { + if (root == null) { + return 0; + } + int sum = preSum * 10 + root.val; + if (root.left == null && root.right == null) { + return sum; + } + return dfs(root.left, sum) + dfs(root.right, sum); + } +} + + +/* +广度优先搜索: +1、使用两个队列,一个存放节点,一个存放根节点到达该节点时“产生的数字”,两个队列一一对应 +2、层序遍历,遍历当前层时,把下一层的节点和“产生的数字”存入队列 +3、到达叶子结点时才将最终“产生的数字”累加到总和中,即将最后一层节点“产生的数字”累加就是根节点到叶节点数字之和 +4、否则持续计算到达新节点时“产生的数字”,并将节点与“产生的数字”保存在队列中 + */ +class Solution { + public int sumNumbers(TreeNode root) { + if (root == null) { + return 0; + } + Queue nodeQueue = new LinkedList<>(); + Queue valQueue = new LinkedList<>(); + nodeQueue.offer(root); + valQueue.offer(root.val); + int sum = 0; + while (!nodeQueue.isEmpty()) { + TreeNode node = nodeQueue.poll(); + int val = valQueue.poll(); + TreeNode left = node.left, right = node.right; + if (left == null && right == null) { + sum += val; + } else { + if (left != null) { + nodeQueue.offer(left); + valQueue.offer(val * 10 + left.val); + } + if (right != null) { + nodeQueue.offer(right); + valQueue.offer(val * 10 + right.val); + } + } + } + return sum; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0130.java b/leetcode_Java/Solution0130.java new file mode 100644 index 0000000..84f89b8 --- /dev/null +++ b/leetcode_Java/Solution0130.java @@ -0,0 +1,42 @@ +// 130. 被围绕的区域 + + +/* +深度优先搜索: +1、遍历四条边界,将边界的 O 换成 Y,剩下的 O 就是被 X 围绕的区域 +2、两层for循环遍历二维数组每个位置,当碰到 O 时,通过深度优先搜索往上下左右四个方向扩散,将 O 换成 X;当碰到 Y 时,将 Y 恢复成 O + */ +class Solution { + public void solve(char[][] board) { + int n = board.length, m = board[0].length; + for (int row = 0; row < n; row++) { + dfs(board, row, 0); + dfs(board, row, m - 1); + } + for (int col = 0; col < m; col++) { + dfs(board, 0, col); + dfs(board, n - 1, col); + } + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (board[row][col] == 'O') { + board[row][col] = 'X'; + } else if (board[row][col] == 'Y') { + board[row][col] = 'O'; + } + } + } + } + + private void dfs(char[][] board, int row, int col) { + int n = board.length, m = board[0].length; + if (row < 0 || col < 0 || row >= n || col >= m || board[row][col] != 'O') { + return; + } + board[row][col] = 'Y'; + dfs(board, row + 1, col); + dfs(board, row - 1, col); + dfs(board, row, col + 1); + dfs(board, row, col - 1); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0131.java b/leetcode_Java/Solution0131.java new file mode 100644 index 0000000..577571c --- /dev/null +++ b/leetcode_Java/Solution0131.java @@ -0,0 +1,47 @@ +// 131. 分割回文串 + + +/* +回溯: +1、使用res存放全局结果,使用track存放子结果 +2、调用递归函数处理得到结果,返回结果 +3、定义递归函数: + 1)终止条件:字符串遍历结束,收集子结果 + 2)剪枝条件:子串是否回文串,不是则跳过,是则递归下一层处理 + 3)单层递归逻辑:遍历字符串,得到一个区间的子串,判断子串是否回文串,是则添加子串到track中,递归下一层处理剩余的字符串,回溯撤销当前层在track添加的子串 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> partition(String s) { + backtrack(s, 0); + return res; + } + + private void backtrack(String s, int startIndex) { + if (startIndex == s.length()) { + res.add(new ArrayList<>(track)); + return; + } + for (int i = startIndex; i < s.length(); i++) { + if (isPalindrome(s, startIndex, i)) { + track.addLast(s.substring(startIndex, i + 1)); + backtrack(s, i + 1); + track.removeLast(); + } + } + } + + // 是否回文串 + private boolean isPalindrome(String s, int start, int end) { + while (start < end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0136.java b/leetcode_Java/Solution0136.java new file mode 100644 index 0000000..eda4c29 --- /dev/null +++ b/leetcode_Java/Solution0136.java @@ -0,0 +1,59 @@ +// 136. 只出现一次的数字 + + +/* +思路:使用HashMap记录每个数出现的次数,遍历HashMap查找只出现一次的数字 + */ +class Solution { + public int singleNumber(int[] nums) { + HashMap map = new HashMap<>(); + for (int num : nums) { + int count = map.getOrDefault(num, 0); + map.put(num, ++count); + } + for (int num : map.keySet()) { + if (map.get(num) == 1) { + return num; + } + } + return -1; + } +} + + +/* +思路:使用列表存放数字。没有出现过则存入,出现过则移除,最后剩下一个只出现一次的数字 + */ +class Solution { + public int singleNumber(int[] nums) { + List list = new ArrayList<>(); + for (int num : nums) { + Integer numObj = num; + if (list.contains(numObj)) { + list.remove(numObj); + } else { + list.add(numObj); + } + } + return list.get(0); + } +} + + +/* +思路: +既满足时间复杂度又满足空间复杂度,就要提到位运算中的异或运算 XOR,主要因为异或运算有以下几个特点: +一个数和 0 做 XOR 运算等于本身:a⊕0 = a +一个数和其本身做 XOR 运算等于 0:a⊕a = 0 +XOR 运算满足交换律和结合律:a⊕b⊕a = (a⊕a)⊕b = 0⊕b = b +故而在以上的基础条件上,将所有数字按照顺序做异或运算,最后剩下的结果即为唯一的数字 + */ +class Solution { + public int singleNumber(int[] nums) { + int res = 0; + for (int num : nums) { + res ^= num; + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0138.java b/leetcode_Java/Solution0138.java new file mode 100644 index 0000000..4e678c0 --- /dev/null +++ b/leetcode_Java/Solution0138.java @@ -0,0 +1,129 @@ +// 138. 复制带随机指针的链表 + + +/* +// Definition for a Node. +class Node { + int val; + Node next; + Node random; + + public Node(int val) { + this.val = val; + this.next = null; + this.random = null; + } +} +*/ + + +/* +递归: +1、成员变量 map 存放新旧节点的映射关系 {原节点:新节点} +2、定义递归函数 + 1)方法功能:入参是一个节点,map存在则直接获取返回,否则拷贝该节点并存入map中,返回拷贝节点 + 2)终止条件:节点为空时返回空 + 3)返回结果:返回该节点的拷贝节点 + 4)递归逻辑:拷贝节点的next指针和random指针需要连接新的拷贝节点,因此调用同样的方法,传入原节点的下一节点和随机节点进行拷贝并返回 + */ +class Solution { + private Map map = new HashMap<>(); + + public Node copyRandomList(Node head) { + if (head == null) { + return null; + } + if (map.containsKey(head)) { + return map.get(head); + } + Node newNode = new Node(head.val); + map.put(head, newNode); + newNode.next = copyRandomList(head.next); + newNode.random = copyRandomList(head.random); + return newNode; + } +} + + +/* +迭代: +1、在每个原节点后面创建一个新节点 +2、设置新节点的随机节点 +3、将两个链表分离 + +1 → 2 → 3 +===================== +1 → 1 → 2 → 2 → 3 → 3 +===================== +------------ +↑ ↓ +1 1 → 2 → 2 → 3 → 3 + ↗ cur p +0 + + */ +class Solution { + public Node copyRandomList(Node head) { + Node p = head; + while (p != null) { + Node newNode = new Node(p.val); + newNode.next = p.next; + p.next = newNode; + p = p.next.next; + } + + p = head; + while (p != null) { + if (p.random != null) { + p.next.random = p.random.next; + } + p = p.next.next; + } + + p = head; + Node root = new Node(0); + Node cur = root; + while (p != null) { + cur.next = p.next; + cur = cur.next; + p.next = p.next.next; + p = p.next; + } + return root.next; + } +} + + +/* +哈希表: +1、创建一个哈希表,再遍历原链表,遍历的同时再不断创建新节点,将原节点作为key,新节点作为value放入哈希表中,原节点和新节点是一一对应的关系,即 + map.get(原节点),得到的就是对应的 新节点 + map.get(原节点.next),得到的就是对应的 新节点.next + map.get(原节点.random),得到的就是对应的 新节点.random +2、再遍历原链表,设置新链表的next和random指针 + 新节点.next -> map.get(原节点.next) + 新节点.random -> map.get(原节点.random) + */ +class Solution { + public Node copyRandomList(Node head) { + Map map = new HashMap<>(); + Node p = head; + while (p != null) { + Node newNode = new Node(p.val); + map.put(p, newNode); + p = p.next; + } + p = head; + while (p != null) { + Node newNode = map.get(p); + if (p.next != null) { + newNode.next = map.get(p.next); + } + if (p.random != null) { + newNode.random = map.get(p.random); + } + p = p.next; + } + return map.get(head); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0139.java b/leetcode_Java/Solution0139.java new file mode 100644 index 0000000..ae1a539 --- /dev/null +++ b/leetcode_Java/Solution0139.java @@ -0,0 +1,141 @@ +// 139. 单词拆分 + + +/* +动态规划: +1、题目:给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s。注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 +2、题目简化:字符串s能否由单词列表拼出 +3、定义dp数组:dp[i]表示前i个字符是否能由单词拼出 +4、初始化: + 1)一维dp数组扩容:增加空字符串这一最小规模的情况,方便初始化 + 2)dp[0] = true,表示字符串为空字符时的情况,方便递推判断 +5、状态转移方程:dp[i] = dp[j] && wordDict.contains(s.substring(j, i)) +6、遍历dp数组填表: + 1)解释一:第一个for循环用于遍历dp数组未知位置,第二个for循环用于遍历dp数组已知位置,得到已知结果后根据状态转移方程推断计算未知结果并填表 + 2)解释二:固定未知位置,由前面已知推断当前结果。固定第i个字符的位置,然后从头开始遍历到i位置,判断s[0,j)和s[j,i)是否能由单词拼出 + 3)i、j的使用:两个for循环中i、j是用于遍历dp数组的,表示dp数组的索引,dp数组的长度比字符串s 大1,用于初始化,字符串s要用i、j时需要根据情况转换成s对应的索引 +7、返回结果:最后一个状态就是结果 + +dp □ □ □ □ □ □ +dp索引 0 1 2 3 4 5 +s a p p l e +s索引 0 1 2 3 4 +s位置 1 2 3 4 5 + */ +class Solution { + public boolean wordBreak(String s, List wordDict) { + int n = s.length(); + boolean[] dp = new boolean[n + 1]; + dp[0] = true; + for (int i = 1; i <= n; i++) { + for (int j = 0; j < i; j++) { + if (dp[j] && wordDict.contains(s.substring(j, i))) { + dp[i] = true; + break; + } + } + } + return dp[n]; + } +} + + +/* +动态规划: +1、题目简化:字符串s能否由单词列表拼出 +2、定义dp数组:dp[i]表示前i个字符是否能由单词拼出 +3、状态转移方程:dp[m] = dp[i] && m <= n && s.startsWith(word, i) +4、初始化:dp[0] = true,表示字符串为空字符时的情况,方便递推判断 +5、遍历dp数组填表: + 1)解释一:第一个for循环用于遍历dp数组,第二个for循环用于遍历单词数组,根据状态转移方程推断计算未知结果并填表 + 2)解释二:固定已知位置,推断后面位置结果。固定第i个字符的位置,且该位置能由单词拼出,然后遍历单词数组,判断扩增一个单词长度的子串是否为s的子串,是则该子串能由单词拼出 + */ +class Solution { + public boolean wordBreak(String s, List wordDict) { + int n = s.length(); + boolean[] dp = new boolean[n + 1]; + dp[0] = true; + for (int i = 0; i < n; i++) { + if (!dp[i]) { + continue; + } + for (String word : wordDict) { + int m = i + word.length(); + if (m <= n && s.startsWith(word, i)) { + dp[m] = true; + } + } + } + return dp[n]; + } +} + + +/* +广度优先: +1、memo[i]表示前i个字符是否能由单词拼出 +2、队列queue存放的是dp[i]的索引i,前i个字符能由单词拼出,再继续判断后面的字符 +3、从队列弹出一个起始索引,遍历单词数组,根据单词扩增子串长度,判断子串长度是否合法、dp是否标记过,是否为s的子串、长度是否达到s的长度, + 满足条件则返回true,否则为有效子串就加入队列继续判断,并标记该子串位置能由单词拼出 +4、遍历结束都不满足则返回false + */ +class Solution { + public boolean wordBreak(String s, List wordDict) { + int n = s.length(); + boolean[] memo = new boolean[n + 1]; + Queue queue = new LinkedList<>(); + queue.add(0); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size > 0) { + int start = queue.poll(); + for (String word : wordDict) { + int nextStart = start + word.length(); + if (nextStart > n || memo[nextStart]) { + continue; + } + if (s.startsWith(word, start)) { + if (nextStart == n) { + return true; + } + memo[nextStart] = true; + queue.add(nextStart); + } + } + size--; + } + } + return false; + } +} + + +/* +深度优先: +1、memo[i]表示前i个字符是否能由单词拼出。被标记为true表示子串能由单词拼出,但是最终不能拼出s,因为递归是一次性判断是否成功,所以该标记用于避免重复处理 +2、dfs(start) 输入参数表示前start个字符能由单词拼出,输出 前start个字符分别拼接单词数组的单词后的子串,是否为s的子串 +3、终止条件:子串有效且达到s的长度时返回true,拼接单词的子串都无效时返回false +4、调用递归函数:子串有效但未达到s的长度,递归判断子串继续拼接单词后,是否有效且达到s的长度 + */ +class Solution { + public boolean wordBreak(String s, List wordDict) { + boolean[] memo = new boolean[s.length() + 1]; + return dfs(s, wordDict, 0, memo); + } + + private boolean dfs(String s, List wordDict, int start, boolean[] memo) { + for (String word : wordDict) { + int nextStart = start + word.length(); + if (nextStart > s.length() || memo[nextStart]) { + continue; + } + if (s.startsWith(word, start)) { + if (nextStart == s.length() || dfs(s, wordDict, nextStart, memo)) { + return true; + } + memo[nextStart] = true; + } + } + return false; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0141.java b/leetcode_Java/Solution0141.java new file mode 100644 index 0000000..851c8c2 --- /dev/null +++ b/leetcode_Java/Solution0141.java @@ -0,0 +1,73 @@ +// 141. 环形链表 + + +/** + * Definition for singly-linked list. + * class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { + * val = x; + * next = null; + * } + * } + */ + + +/* +思路:使用列表存放节点对象,遍历链表,如果节点对象在列表中出现过则有环,否则无环 +注意:列表不能存放节点值,值可能一样,值一样的对象地址不一样,是唯一的 + */ +public class Solution { + public boolean hasCycle(ListNode head) { + List list = new ArrayList<>(); + while (head != null) { + if (list.contains(head)) { + return true; + } + list.add(head); + head = head.next; + } + return false; + } +} + + +/* +使用HashMap存放节点对象 + */ +public class Solution { + public boolean hasCycle(ListNode head) { + HashMap map = new HashMap(); + while (head != null) { + if (map.getOrDefault(head, 0) == 1) { + return true; + } + map.put(head, 1); + head = head.next; + } + return false; + } +} + + +/* +快慢指针: +1、慢指针走一步,快指针走两步 +2、如果没有环,则快指针会走到空指针 +3、如果有环,假设在环中,以快指针为起点,快指针距离慢指针n步,那么当慢指针走n步后的位置为2n,刚好快指针也走2n步,所以会快慢指针会相遇 + */ +public class Solution { + public boolean hasCycle(ListNode head) { + ListNode fast = head; + ListNode slow = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0142.java b/leetcode_Java/Solution0142.java new file mode 100644 index 0000000..45256bf --- /dev/null +++ b/leetcode_Java/Solution0142.java @@ -0,0 +1,85 @@ +// 142. 环形链表 II + + +/** + * Definition for singly-linked list. + * class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { + * val = x; + * next = null; + * } + * } + */ + + +/* +思路:使用列表存放节点对象,遍历链表,如果节点对象在列表中出现过则该节点为开始入环的第一个节点 +注意:列表不能存放节点值,值可能一样,值一样的对象地址不一样,是唯一的 + */ +public class Solution { + public ListNode detectCycle(ListNode head) { + List list = new ArrayList<>(); + while (head != null) { + if (list.contains(head)) { + return head; + } + list.add(head); + head = head.next; + } + return null; + } +} + + +/* +使用HashMap存放节点对象 + */ +public class Solution { + public ListNode detectCycle(ListNode head) { + HashMap map = new HashMap(); + while (head != null) { + if (map.getOrDefault(head, 0) == 1) { + return head; + } + map.put(head, 1); + head = head.next; + } + return null; + } +} + + +/* +快慢指针: +1、慢指针走一步,快指针走两步 +2、如果没有环,则快指针会走到空指针 +3、如果有环,假设在环中,以快指针为起点,快指针距离慢指针n步,那么当慢指针走n步后的位置为2n,刚好快指针也走2n步,所以快慢指针会相遇 +4、入环口位置分析: + 1)设非环部分长度为a,环部分长度为b,快慢相遇时,慢指针走了s,快指针走了2s,快指针比慢指针多走了n次b,所以2s=s+nb,即s=nb + 2)从链表头部走到入环口需要a+nb步。即走a步到了入环口,每绕一圈b步都会回到入环口 + 3)由s=nb知慢指针已经走了nb步,走到入环口需要a+nb步,所以慢指针再走a步就可以到入环口了,而从链表头部走到入环口也是a步,所以慢指针与头指针继续走直到相遇的位置就是入环口 + +1 → 2 → 3 → 4 → 5 + ↑ ↓ + 7 ← 6 + */ +public class Solution { + public ListNode detectCycle(ListNode head) { + ListNode fast = head; + ListNode slow = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + while (head != slow) { + head = head.next; + slow = slow.next; + } + return head; + } + } + return null; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0143.java b/leetcode_Java/Solution0143.java new file mode 100644 index 0000000..25531c9 --- /dev/null +++ b/leetcode_Java/Solution0143.java @@ -0,0 +1,146 @@ +// 143. 重排链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +注意:不是使用第三个链表去重新连接原链表,而是直接获取原链表节点改变其指针指向 +1、使用列表存放节点,双指针从头尾取节点,改变节点连接顺序 +2、left、right指针指向的节点表示 准备用来修改它的下一指针方向的节点 +3、奇数个节点时,最后一次指针移动是right指针左移,此时 left == right 进入不了下一轮循环 + 偶数个节点时,最后一次指针移动是left指针右移,此时 left == right,由于程序下面还有右指针节点处理逻辑,所以需要提前跳出循环 + + 1 2 3 1 2 3 4 + ↑ ↑ ↑ ↑ +left right left right + + 1 2 3 4 5 6 7 +left right +============================== + 1 2 3 4 5 6 7 + left right +============================== + 1 → 7 → 2 + */ +class Solution { + public void reorderList(ListNode head) { + List list = new ArrayList<>(); + while (head != null) { + list.add(head); + head = head.next; + } + int left = 0, right = list.size() - 1; + while (left < right) { + list.get(left).next = list.get(right); + left++; + if (left == right) { + break; + } + list.get(right).next = list.get(left); + right--; + } + list.get(left).next = null; + } +} + + +/* +思路:利用快慢指针找到链表中点,链表后半部分反转得到新链表,两个链表从头开始改变对应节点指针方向 +1、前三个节点为空则直接结束,因为交换至少需要三个节点 +2、快慢指针从头节点开始,慢指针每次走一步,快指针每次走两步。 + 快指针遇到空时说明走到末尾了,fast.next为空是奇数个节点的情况,fast.next.next为空是偶数个节点的情况 +3、后半部分链表反转,前半部分尾部断开,形成两个链表 +4、两个链表从头开始,改变对应节点的指针方向 + + 1 → 2 → 3 → 4 → 5 → 6 → 7 +head/slow/fast +==================================================== + 1 → 2 → 3 → 4 → 5 → 6 → 7 + head slow fast +==================================================== + 1 → 2 → 3 → 4 7 → 6 → 5 + head newHead newHeadNext +==================================================== + 1 → 7 → 2 → 3 → 4 6 → 5 + head newHead newHeadNext +==================================================== + 1 → 7 → 2 → 3 → 4 6 → 5 + head newHead newHeadNext + */ +class Solution { + public void reorderList(ListNode head) { + if (head == null || head.next == null || head.next.next == null) { + return; + } + ListNode slow = head, fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + ListNode newHead = reverse(slow.next); + slow.next = null; + while (newHead != null) { + ListNode newHeadNext = newHead.next; + newHead.next = head.next; + head.next = newHead; + head = newHead.next; + newHead = newHeadNext; + } + } + + // 206.反转链表 + private ListNode reverse(ListNode head) { + ListNode before = null, after; + while (head != null) { + after = head.next; + head.next = before; + before = head; + head = after; + } + return before; + } +} + + +/* +递归 + */ +class Solution { + public void reorderList(ListNode head) { + int count = 0; + ListNode cur = head; + while(cur != null){ + cur = cur.next; + count++; + } + if(count <= 2) { + return; + } + reorderList(head, count); + } + + private ListNode reorderList(ListNode head, int count){ + if(count == 1) { + return head; + } else if (count == 2) { + return head.next; + } + ListNode midTail = reorderList(head.next, count - 2); + ListNode headNext = head.next; + ListNode after = midTail.next; + midTail.next = after.next; + head.next = after; + after.next = headNext; + return midTail; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0144.java b/leetcode_Java/Solution0144.java new file mode 100644 index 0000000..67ba97d --- /dev/null +++ b/leetcode_Java/Solution0144.java @@ -0,0 +1,234 @@ +// 144. 二叉树的前序遍历 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路:遍历⼀遍⼆叉树,结果记录在全局变量中 +1、定义数据结构:使用列表成员变量,存储每次递归操作存入的值 +2、递归终止条件:节点为空时返回 +3、单层递归逻辑:把节点的值存入列表 +4、递归逻辑: + 左右节点需要与根节点做同样的事,就要调同样的方法,即递归 + 确定递归顺序/遍历顺序,中左右 + 每层不需要接收使用递归方法返回值,列表成员变量存储了结果 +=================================================== +新模板注释,递归 +节点值加入列表递归函数 +1、方法功能:入参是一个节点,将该节点值加入列表,返回列表 +2、终止条件:节点为空时,返回列表 +3、一个节点处理过程和返回结果:将节点值加入列表,返回列表 +4、递归调用:左右节点同样需要加入列表,因此调用同样的方法处理 +5、递归顺序:前序遍历,先处理根节点,再处理左节点,最后处理右节点 +6、使用递归调用结果和返回结果:不用接收递归调用结果,节点已经加入列表了,直接返回列表即可 +* */ +class Solution { + public List list = new ArrayList<>(); + public List preorderTraversal(TreeNode root) { + if (root == null) { + return list; + } + list.add(root.val); + preorderTraversal(root.left); + preorderTraversal(root.right); + return list; + } +} + + +/* +递归思路:分解问题计算出答案。通过维护局部变量,存放子问题的结果,将子结果返回给上一层使用,层层累计处理,得到最终结果 + */ +class Solution { + public List preorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) { + return res; + } + res.add(root.val); + res.addAll(preorderTraversal(root.left)); + res.addAll(preorderTraversal(root.right)); + return res; + } +} + + +/* + * 迭代思路: + * 1、定义数据结构:局部变量即可,列表存放结果数据,栈按序存放节点,指针指向下一个要处理的节点 + * 2、遍历条件、操作逻辑: + * 如果当前节点为空,则从栈弹出节点 + * 存入当前节点值;右节点入栈,用来后面获取右节点的值;指向左节点 + * */ +class Solution { + public List preorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + if (cur == null) { + cur = stack.pop(); + } + list.add(cur.val); + if (cur.right != null) { + stack.push(cur.right); + } + cur = cur.left; + } + return list; + } +} + + +/* + * 迭代思路: + * 1、定义数据结构:局部变量即可,列表存放结果数据,栈按序存放节点,指针指向下一个要处理的节点 + * 2、遍历条件、操作逻辑: + * 存入当前节点值;当前节点入栈,用来后面获取右节点;指向左节点 + * */ +class Solution { + public List preorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + while (cur != null) { + list.add(cur.val); + stack.push(cur); + cur = cur.left; + } + cur = stack.pop(); + cur = cur.right; + } + return list; + } +} + + +/* + * 迭代思路: + * 1、定义数据结构:局部变量即可,列表存放结果数据,栈按序存放节点 + * 2、遍历条件、操作逻辑: + * 存入当前节点值;右节点入栈;左节点入栈 + * 3、用左节点入栈弹出的方式代替了指针标记下一个要处理的节点 + * */ +class Solution { + public List preorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + if (root == null) { + return list; + } + stack.push(root); + while (!stack.isEmpty()) { + root = stack.pop(); + list.add(root.val); + if (root.right != null) { + stack.push(root.right); + } + if (root.left != null) { + stack.push(root.left); + } + } + return list; + } +} + + +/* + * 迭代思路: + * 1、定义数据结构:结果列表存放排序节点值;节点列表按序存放节点;索引列表存放未判断是否有左右子节点的节点 + * 2、数据结构初始化:根节点存入节点列表;索引0存入索引列表 + * 3、迭代逻辑: + * 1)索引列表不为空时,说明有节点未判断是否有左右子节点,循环遍历索引列表 + * 2)索引列表降序排序,取出最大索引,对该索引的节点进行操作。先处理靠右边的节点,可以防止插入节点时影响了节点列表其他节点的位置 + * 3)是否有子节点存在四种情况:有左右节点、只有右节点、只有左节点、没有左右节点。要分别处理,不同情况节点最终索引位置不同 + * 4)前序遍历: + * 先插入右节点,再插入左节点 + * 插入左右节点都是在根节点右边插入,其他结点右移一位 + * 5)最大索引的节点判断完左右节点后,移除索引列表的最大索引 + * 6)最终节点列表按序排序,遍历结点列表,将节点值存入结果列表 + * */ +class Solution { + public List preorderTraversal(TreeNode root) { + List resList = new ArrayList<>(); + if (root == null) { + return resList; + } + List nodeList = new ArrayList<>(); + List indexList = new ArrayList<>(); + nodeList.add(root); + indexList.add(0); + while(!indexList.isEmpty()) { + indexList.sort((o1, o2) -> o2 - o1); + int index = indexList.get(0); + root = nodeList.get(index); + if (root.left != null && root.right != null) { + nodeList.add(index + 1, root.right); + nodeList.add(index + 1, root.left); + indexList.add(index + 2); + indexList.add(index + 1); + } else if (root.left != null) { + nodeList.add(index + 1, root.left); + indexList.add(index + 1); + } else if (root.right != null) { + nodeList.add(index + 1, root.right); + indexList.add(index + 1); + } + indexList.remove(0); + } + for (TreeNode node : nodeList) { + resList.add(node.val); + } + return resList; + } +} + + +/* + * 迭代思路: + * 1、简单理解:把左子树塞到根节点和右节点中间,每个节点都要做同样的操作 + * 2、节点连接步骤: + * 1)前序遍历是中左右,即根节点→左子树→右子树 + * 2)左子树遍历的最后一个节点是 左子树的最后一个右子节点,因此要将其连接到根节点的右节点上 + * 3)根节点的右指针要指向左节点,左指针指向空,从而形成中左右的链表 + * 2、遍历逻辑: + * 1)根指针的移动代表着前序遍历的顺序,循环遍历条件是根指针不为空 + * 2)如果根节点的左节点不为空,则进行节点连接步骤;如果为空,则将节点值存入列表,根指针指向右节点 + * 3、“114.二叉树展开为链表”的解法 + * */ +class Solution { + public List flatten(TreeNode root) { + List list = new ArrayList<>(); + while (root != null) { + if (root.left != null) { + TreeNode temp = root.left; + while (temp.right != null) { + temp = temp.right; + } + temp.right = root.right; + root.right = root.left; + root.left = null; + } else { + list.add(root.val); + root = root.right; + } + } + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0145.java b/leetcode_Java/Solution0145.java new file mode 100644 index 0000000..124d107 --- /dev/null +++ b/leetcode_Java/Solution0145.java @@ -0,0 +1,179 @@ +// 145. 二叉树的后序遍历 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、定义数据结构:使用列表成员变量,存储每次递归操作存入的值 +2、递归终止条件:节点为空时返回 +3、单层递归逻辑:把节点的值存入列表 +4、递归逻辑: + 左右节点需要与根节点做同样的事,就要调同样的方法,即递归 + 确定递归顺序/遍历顺序,左右中 + 每层不需要接收使用递归方法返回值,列表成员变量存储了结果 +==================================================== +新模板注释,递归 +节点值加入列表递归函数 +1、方法功能:入参是一个节点,将该节点值加入列表,返回列表 +2、终止条件:节点为空时,返回列表 +3、一个节点处理过程和返回结果:将节点值加入列表,返回列表 +4、递归调用:左右节点同样需要加入列表,因此调用同样的方法处理 +5、递归顺序:后序遍历,先处理左节点,再处理右节点,最后处理根节点 +6、使用递归调用结果和返回结果:不用接收递归调用结果,节点已经加入列表了,直接返回列表即可 + * */ +class Solution { + public List list = new ArrayList<>(); + public List postorderTraversal(TreeNode root) { + if (root == null) { + return list; + } + postorderTraversal(root.left); + postorderTraversal(root.right); + list.add(root.val); + return list; + } +} + + +/* + * 迭代思路: + * 1、定义数据结构:局部变量即可,列表存放结果数据,栈按序存放节点 + * 2、遍历条件、操作逻辑: + * 如果当前节点为空,则从栈弹出节点 + * 存入节点值,预存右节点入栈,指向左节点 + * */ +class Solution { + public List postorderTraversal(TreeNode root) { + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode pre = null; + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + while (cur != null) { + stack.push(cur); + cur = cur.left; + } + cur = stack.pop(); + if (cur.right == null || cur.right == pre) { + list.add(cur.val); + pre = cur; + cur = null; + } else { + stack.push(cur); + cur = cur.right; + } + } + return list; + } +} + + +/* +* 迭代思路:144题,前序遍历的迭代思路,结果数组反转 +* */ + + +/* + * 迭代思路: + * 1、定义数据结构:结果列表存放排序节点值;节点列表按序存放节点;索引列表存放未判断是否有左右子节点的节点 + * 2、数据结构初始化:根节点存入节点列表;索引0存入索引列表 + * 3、迭代逻辑: + * 1)索引列表不为空时,说明有节点未判断是否有左右子节点,循环遍历索引列表 + * 2)索引列表降序排序,取出最大索引,对该索引的节点进行操作。先处理靠右边的节点,可以防止插入节点时影响了节点列表其他节点的位置 + * 3)是否有子节点存在四种情况:有左右节点、只有右节点、只有左节点、没有左右节点。要分别处理,不同情况节点最终索引位置不同 + * 4)后序遍历: + * 先插入右节点,再插入左节点 + * 插入左右节点都是替代了根节点的位置,其他结点右移一位 + * 5)最大索引的节点判断完左右节点后,移除索引列表的最大索引 + * 6)最终节点列表按序排序,遍历结点列表,将节点值存入结果列表 + * */ +class Solution { + public List postorderTraversal(TreeNode root) { + List resList = new ArrayList<>(); + if (root == null) { + return resList; + } + List nodeList = new ArrayList<>(); + List indexList = new ArrayList<>(); + nodeList.add(root); + indexList.add(0); + while(!indexList.isEmpty()) { + indexList.sort((o1, o2) -> o2 - o1); + int index = indexList.get(0); + root = nodeList.get(index); + if (root.left != null && root.right != null) { + nodeList.add(index, root.right); + nodeList.add(index, root.left); + indexList.add(index + 1); + indexList.add(index); + } else if (root.left != null) { + nodeList.add(index, root.left); + indexList.add(index); + } else if (root.right != null) { + nodeList.add(index, root.right); + indexList.add(index); + } + indexList.remove(0); + } + for (TreeNode node : nodeList) { + resList.add(node.val); + } + return resList; + } +} + + +/* + * 迭代思路: + * 1、定义数据结构:列表存放节点值;栈按序存放节点;哈希表标记节点是否已处理过左右节点 + * 2、数据结构初始化:根节点入栈 + * 3、迭代逻辑: + * 1)栈不为空时遍历栈,弹出栈顶节点 + * 2)判断当前节点是否已经处理过左右节点,处理过则节点值存入列表 + * 3)没有则将节点按中右左顺序入栈,弹出时才会是左右中,标记当前节点已处理 + * 4、标记目的:节点已经遍历过,但又暂时不能存入列表,所以需要先按序暂存在栈中,按序弹出再存入列表 + * 作用与递归相同,递归是使用栈帧保存当前变量,当下一层处理完成后,就可以回到当前栈帧的状态,处理当前的数据 + * */ +class Solution { + public List postorderTraversal(TreeNode root) { + List resList = new ArrayList<>(); + if (root == null) { + return resList; + } + Map flagMap = new HashMap<>(); + Stack stack = new Stack<>(); + stack.add(root); + while (!stack.isEmpty()) { + root = stack.pop(); + if (flagMap.getOrDefault(root, false)) { + resList.add(root.val); + } else { + stack.push(root); + if (root.right != null) { + stack.push(root.right); + } + if (root.left != null) { + stack.push(root.left); + } + flagMap.put(root, true); + } + } + return resList; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0146.java b/leetcode_Java/Solution0146.java new file mode 100644 index 0000000..d7626e3 --- /dev/null +++ b/leetcode_Java/Solution0146.java @@ -0,0 +1,148 @@ +// 146. LRU 缓存 + + +/** + * Your LRUCache object will be instantiated and called as such: + * LRUCache obj = new LRUCache(capacity); + * int param_1 = obj.get(key); + * obj.put(key,value); + */ + + +/* +1、LRU:最近最久未使用,缓存淘汰算法 +2、LinkedHashMap 哈希链表 = 双向链表 + 哈希表 + 1)哈希表:查找快,但是无序 + 2)链表:有序,插入、删除快,但是查找慢 + */ + + +// 使用Java的API LinkedHashMap +class LRUCache extends LinkedHashMap { + + private int capacity; + + public LRUCache(int capacity) { + super(capacity, 0.75F, true); + this.capacity = capacity; + } + + public int get(int key) { + return super.getOrDefault(key, -1); + } + + public void put(int key, int value) { + super.put(key, value); + } + + // 删除最近最久未使用节点 + @Override + protected boolean removeEldestEntry(Map.Entry entry) { + return size() > capacity; + } +} + + +/* +LRUCache类,即手动实现哈希链表、缓存淘汰机制: +1、定义 双向链表节点内部类,包含 公有成员变量“键、值、前驱节点、后驱节点”、构造方法 +2、定义 私有成员变量“HashMap缓存、链表大小、链表容量、链表头尾哨兵节点” +3、定义 公有构造方法,初始化成员变量 +4、定义 私有方法,处理链表节点,添加节点到头部、删除节点、移动节点到头部、删除尾部节点 +5、实现获取节点值 + 1)根据key从缓存中获取节点 + 2)如果节点不存在,返回-1 + 3)如果节点存在,当前被使用了,移动节点到头部 +6、实现存入节点 + 1)根据key从缓存中获取节点 + 2)如果节点不存在 + ① 创建节点、添加节点到缓存、添加节点到头部、链表大小加1 + ② 判断链表大小是否超过链表容量,超过则 删除尾部节点、删除该节点缓存、链表大小减1 + 3)如果节点存在,更新节点值、移动节点到头部 + */ +class LRUCache { + // 内部类,双向链表节点 + class DoubleLinkedNode { + int key; + int value; + DoubleLinkedNode prev; + DoubleLinkedNode next; + + public DoubleLinkedNode() {} + + public DoubleLinkedNode(int key, int value) { + this.key = key; + this.value = value; + } + } + + private Map cache = new HashMap<>(); // 缓存 + private int size; // 大小 + private int capacity; // 容量 + private DoubleLinkedNode head, tail; // 头尾哨兵节点 + + public LRUCache(int capacity) { + this.size = 0; + this.capacity = capacity; + this.head = new DoubleLinkedNode(); + this.tail = new DoubleLinkedNode(); + this.head.next = this.tail; + this.tail.prev = this.head; + } + + // 获取节点值 + public int get(int key) { + DoubleLinkedNode node = cache.get(key); + if (node == null) { + return -1; + } + moveToHead(node); + return node.value; + } + + // 存入节点 + public void put(int key, int value) { + DoubleLinkedNode node = cache.get(key); + if (node == null) { + DoubleLinkedNode newNode = new DoubleLinkedNode(key, value); + cache.put(key, newNode); + addToHead(newNode); + this.size++; + if (this.size > this.capacity) { + DoubleLinkedNode tailNode = removeTail(); + cache.remove(tailNode.key); + this.size--; + } + } else { + node.value = value; + moveToHead(node); + } + } + + // 添加节点到头部 + private void addToHead(DoubleLinkedNode node) { + node.prev = this.head; + node.next = this.head.next; + this.head.next.prev = node; + this.head.next = node; + } + + // 删除节点 + private void removeNode(DoubleLinkedNode node) { + node.prev.next = node.next; + node.next.prev = node.prev; + } + + // 移动节点到头部:删除节点、添加节点到头部 + private void moveToHead(DoubleLinkedNode node) { + removeNode(node); + addToHead(node); + } + + // 删除尾部节点 + private DoubleLinkedNode removeTail() { + DoubleLinkedNode node = this.tail.prev; + removeNode(node); + return node; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0148.java b/leetcode_Java/Solution0148.java new file mode 100644 index 0000000..8606722 --- /dev/null +++ b/leetcode_Java/Solution0148.java @@ -0,0 +1,97 @@ +// 148. 排序链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +递归,归并排序: +1、方法功能:通过快慢指针找到链表中点,将链表拆分成两个链表,然后“21.合并两个有序链表”,返回新链表头节点 +2、终止条件:节点为空 或 下一节点为空,则直接返回该节点,因为至少需要两个节点才能排序 +3、递归逻辑:传入节点拆分成两个链表后,对两个链表有序合并。拆分后的两个新链表需要同样的操作,因此调用递归方法处理 + */ +class Solution { + public ListNode sortList(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode slow = head, fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + ListNode newHead = slow.next; + slow.next = null; + ListNode left = sortList(head); + ListNode right = sortList(newHead); + ListNode root = new ListNode(0); + ListNode cur = root; + while (left != null && right != null) { + if (left.val < right.val) { + cur.next = left; + left = left.next; + } else { + cur.next = right; + right = right.next; + } + cur = cur.next; + } + cur.next = left != null ? left : right; + return root.next; + } +} + + +/* +优先级队列升序排序,再弹出节点修改下一指针连接方向 + */ +class Solution { + public ListNode sortList(ListNode head) { + PriorityQueue queue = new PriorityQueue<>((x, y) -> x.val - y.val); + while (head != null) { + queue.add(head); + head = head.next; + } + ListNode root = new ListNode(0); + ListNode cur = root; + while (!queue.isEmpty()) { + ListNode node = queue.poll(); + cur.next = node; + cur = cur.next; + } + cur.next = null; + return root.next; + } +} + + +/* +节点值存入列表,升序排序,再取出创建节点连接成链表 + */ +class Solution { + public ListNode sortList(ListNode head) { + List list = new ArrayList<>(); + while (head != null) { + list.add(head.val); + head = head.next; + } + Collections.sort(list); + ListNode root = new ListNode(0); + ListNode cur = root; + for (int val : list) { + ListNode node = new ListNode(val); + cur.next = node; + cur = cur.next; + } + return root.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0151.java b/leetcode_Java/Solution0151.java new file mode 100644 index 0000000..ed7f4f1 --- /dev/null +++ b/leetcode_Java/Solution0151.java @@ -0,0 +1,87 @@ +// 151. 颠倒字符串中的单词 + + +/* +1、字符串去掉头尾空格,按空格分隔字符串,倒序拼接单词 +2、拼接单词字符串可以使用StringBuilder直接构造,也可以先把单词加到列表最后拼接 + */ +class Solution { + public String reverseWords(String s) { + String[] splits = s.trim().split(" "); + StringBuilder res = new StringBuilder(); + for (int i = splits.length - 1; i >= 0; i--) { + String word = splits[i]; + if (word == "") { + continue; + } + res.append(word); + if (i > 0) { + res.append(" "); + } + } + return res.toString(); + } +} + + +/* +去掉头尾空格,正则表达式\\s+ 连续空白字符作为分隔符,得到单词列表,列表反转,再通过空格字符连接成字符串 + */ +class Solution { + public String reverseWords(String s) { + s = s.trim(); + List list = Arrays.asList(s.split("\\s+")); + Collections.reverse(list); + return String.join(" ", list); + } +} + + +/* +双指针:从右到左,跳过空格,遍历得到一个单词的索引区间,将单词加入列表,最后列表通过空格字符连接成字符串 + */ +class Solution { + public String reverseWords(String s) { + s = s.trim(); + int n = s.length(); + int left = n - 1, right = n - 1; + List list = new ArrayList<>(); + while (left >= 0) { + while (left >= 0 && s.charAt(left) != ' ') { + left--; + } + list.add(s.substring(left + 1, right + 1)); + while (left >= 0 && s.charAt(left) == ' ') { + left--; + } + right = left; + } + return String.join(" ", list); + } +} + + +/* +双端队列:从左到右,遍历字符构造出一个单词,遇到空格时且单词不为空就将单词加到队列头部,最后队列通过空格字符连接成字符串 + */ +class Solution { + public String reverseWords(String s) { + s = s.trim(); + s += " "; + int n = s.length(); + int left = 0, right = n - 1; + Deque queue = new ArrayDeque<>(); + StringBuilder word = new StringBuilder(); + while (left <= right) { + char c = s.charAt(left); + if (word.length() != 0 && c == ' ') { + queue.offerFirst(word.toString()); + word.setLength(0); + } else if (c != ' ') { + word.append(s.charAt(left)); + } + left++; + } + return String.join(" ", queue); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0152.java b/leetcode_Java/Solution0152.java new file mode 100644 index 0000000..2953e88 --- /dev/null +++ b/leetcode_Java/Solution0152.java @@ -0,0 +1,72 @@ +// 152. 乘积最大子数组 + + +/* +1、res记录子数组最大乘积,imax表示以nums[i]结尾的子数组最大乘积,imin表示以nums[i]结尾的子数组最小乘积 +2、遍历数据,计算当前最大值,不断更新res +3、由于存在负数,那么会导致最大的变最小的,最小的变最大的。因此还需要维护当前最小值imin,当负数出现时则imax与imin进行交换再进行下一步计算 + */ +class Solution { + public int maxProduct(int[] nums) { + int res = nums[0], imax = 1, imin = 1; + for (int i = 0; i < nums.length; i++) { + if (nums[i] < 0) { + int temp = imax; + imax = imin; + imin = temp; + } + imax = Math.max(imax * nums[i], nums[i]); + imin = Math.min(imin * nums[i], nums[i]); + res = Math.max(res, imax); + } + return res; + } +} + + +/* +动态规划: +1、题目:给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。 +2、题目简化:求数组的最大乘积 +3、定义dp数组:dpMax[i]表示以i位置结尾的子数组最大乘积,dpMin[i]表示以i位置结尾的子数组最小乘积。由于存在负数,因此要保留当前的最大最小值。 +4、初始化: + 1)一维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)dpMax[0] = dpMin[0] = nums[0]; +5、状态转移方程: + dpMax[i] = Math.max(nums[i], Math.max(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i])); + dpMin[i] = Math.min(nums[i], Math.min(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i])); +6、遍历dp数组填表:一个for循环遍历dp数组的未知位置,根据状态转移方程直接取dp数组的已知结果计算未知结果 +7、返回结果:dpMax[i]中取最大值 + */ +class Solution { + public int maxProduct(int[] nums) { + int n = nums.length; + int res; + int[] dpMax = new int[n]; + int[] dpMin = new int[n]; + res = dpMax[0] = dpMin[0] = nums[0]; + for (int i = 1; i < n; i++) { + dpMax[i] = Math.max(nums[i], Math.max(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i])); + dpMin[i] = Math.min(nums[i], Math.min(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i])); + res = Math.max(res, dpMax[i]); + } + return res; + } +} + + +/* +优化空间,使用变量替代dp数组 + */ +class Solution { + public int maxProduct(int[] nums) { + int res = nums[0], imax = 1, imin = 1; + for (int i = 0; i < nums.length; i++) { + int imaxOld = imax, iminOld = imin; + imax = Math.max(nums[i], Math.max(imaxOld * nums[i], iminOld * nums[i])); + imin = Math.min(nums[i], Math.min(imaxOld * nums[i], iminOld * nums[i])); + res = Math.max(res, imax); + } + return res; + } +} diff --git a/leetcode_Java/Solution0153.java b/leetcode_Java/Solution0153.java new file mode 100644 index 0000000..8c2048a --- /dev/null +++ b/leetcode_Java/Solution0153.java @@ -0,0 +1,107 @@ +// 153. 寻找旋转排序数组中的最小值 + + +/* +二分查找:二分寻找最小值索引 +-------------------------------------------------------------------- +递增序列: + * + * + * + * +* +============== +旋转序列: + 1)旋转后的左段最小值大于右段最大值 + 2)中点在断崖左段时 nums[mid] > nums[right],最小值在右半部分 + 3)中点在断崖右段时 nums[mid] < nums[right],最小值在左半部分 + * +* + * + * + * +--------------------------------------------------------------------- +例一: 1 2 3 4 5 + 右排序数组 +例二: 3 4 5 | 1 2 + 左排序数组 右排序数组 + +1、寻找旋转数组的最小元素即为寻找 右排序数组 的首个元素 nums[x],称 x 为 旋转点 +2、左排序数组任一元素 >= 右排序数组任一元素 +3、中值跟右值比较,而不跟左值比较的原因是,右值一定在右排序数组,左值不一定在左排序数组,所以跟左值比较时不能确定中值在哪个排序数组,从而无法确定缩小区间范围 + 如例一左值在右排序数组,例二左值在左排序数组 +--------------------------------------------------------------------- +3 4 5 1 2 +↑ ↑ ↑ +l mid r +============== +3 4 5 1 2 + ↑ ↑ + l/mid r +============== +3 4 5 1 2 + ↑ + l/r + */ +class Solution { + public int findMin(int[] nums) { + int left = 0, right = nums.length - 1; // 左闭右闭区间,如果用右开区间则不方便判断右值 + while (left < right) { // 循环不变式,如果left == right,则循环结束 + int mid = (left + right) / 2; // 向下取整,mid更靠近left,即 left <= mid < right,mid右边的元素必然存在,所以要跟右值比较 + if (nums[mid] < nums[right]) { // 中值小于右值,则右半部分必然递增,最小值在左半部分,收缩右边界 + right = mid; // 由于中值是小值,所以也可能是最小值,右边界要包括中值 + } else { + left = mid + 1; // 中值大于右值,最小值在右半部分,由于中值是大值,所以左边界不用包括中值 + } + } + return nums[left]; // 循环结束,left == right,返回最小值 + } +} + + +/* +二分查找:二分寻找最大值索引,下一位就是最小值,索引加1对数组长度取余 即为最小值索引 + +3 4 5 1 2 +↑ ↑ ↑ +l mid r +============== +3 4 5 1 2 + ↑ ↑ ↑ + l mid r +============== +3 4 5 1 2 + ↑ + l/r + */ +class Solution { + public int findMin(int[] nums) { + int n = nums.length; + int left = 0, right = n - 1; // 左闭右闭区间,如果用左开区间则不方便判断左值 + while (left < right) { // 循环不变式,如果left == right,则循环结束 + int mid = (left + right + 1) / 2; // 先加1再向下取整,mid更靠近right,即 left < mid <= right,mid左边的元素必然存在,所以要跟左值比较 + if (nums[left] < nums[mid]) { // 左值小于中值,则左半部分必然递增,最大值在左半部分,收缩左边界 + left = mid; // 由于中值是大值,所以也可能是最大值,左边界要包括中值 + } else { + right = mid - 1; // 左值大于中值,最大值在左半部分,由于中值是小值,所以右边界不用包括中值 + } + } + return nums[(left + 1) % n]; // 最大值下一位就是最小值 + } +} + + +/* +一次遍历,当前元素小于前一元素时,该元素时最小值 + */ +class Solution { + public int findMin(int[] nums) { + int n = nums.length; + for (int i = 1; i < n; i++) { + if (nums[i] < nums[i - 1]) { + return nums[i]; + } + } + return nums[0]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0154.java b/leetcode_Java/Solution0154.java new file mode 100644 index 0000000..1967570 --- /dev/null +++ b/leetcode_Java/Solution0154.java @@ -0,0 +1,43 @@ +// 154. 寻找旋转排序数组中的最小值 II +// 剑指offer同题“11. 旋转数组的最小数字” + +/* +1、二分查找,比“153. 寻找旋转排序数组中的最小值”多了重复元素 +2、当中值等于右值时,无法区分二段性,让右指针左移,去掉一个干扰项 + +7 0 1 1 1 1 1 2 3 4 +↑ ↑ ↑ +l m r +============================= +7 0 1 1 1 1 1 2 3 4 +↑ ↑ ↑ +l m r +============================= +7 0 1 1 1 1 1 2 3 4 +↑ ↑ ↑ +l m r +============================= +7 0 1 1 1 1 1 2 3 4 +↑ ↑ +l/m r +============================= +7 0 1 1 1 1 1 2 3 4 + ↑ + l/r + */ +class Solution { + public int findMin(int[] nums) { + int left = 0, right = nums.length - 1; + while (left < right) { + int mid = (left + right) / 2; + if (nums[mid] < nums[right]) { + right = mid; + } else if (nums[mid] > nums[right]) { + left = mid + 1; + } else { + right--; + } + } + return nums[left]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0155.java b/leetcode_Java/Solution0155.java new file mode 100644 index 0000000..c3233c1 --- /dev/null +++ b/leetcode_Java/Solution0155.java @@ -0,0 +1,81 @@ +// 155. 最小栈 + + +/* +使用辅助栈,与元素栈同步插入与删除,用于存储与每个元素当前对应的最小值 + */ +class MinStack { + + Stack stack, minStack; + + public MinStack() { + stack = new Stack(); + minStack = new Stack(); + minStack.push(Integer.MAX_VALUE); + } + + public void push(int val) { + stack.push(val); + minStack.push(Math.min((int) minStack.peek(), val)); + } + + public void pop() { + stack.pop(); + minStack.pop(); + } + + public int top() { + return (int) stack.peek(); + } + + public int getMin() { + return (int) minStack.peek(); + } +} + + +/* +变量保存当前最小值,栈同时保存历史最小值,防止历史最小值丢失 + */ +class MinStack { + + Stack stack; + int minVal; + + public MinStack() { + stack = new Stack(); + minVal = Integer.MAX_VALUE; + } + + public void push(int val) { + if (val <= minVal) { + stack.push(minVal); + minVal = val; + } + stack.push(val); + } + + public void pop() { + if ((int) stack.pop() == minVal) { + minVal = (int) stack.pop(); + } + } + + public int top() { + return (int) stack.peek(); + } + + public int getMin() { + return minVal; + } +} + + +/** + * Your MinStack object will be instantiated and called as such: + * MinStack obj = new MinStack(); + * obj.push(val); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ \ No newline at end of file diff --git a/leetcode_Java/Solution0160.java b/leetcode_Java/Solution0160.java new file mode 100644 index 0000000..8a62251 --- /dev/null +++ b/leetcode_Java/Solution0160.java @@ -0,0 +1,53 @@ +// 160. 相交链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { + * val = x; + * next = null; + * } + * } + */ + + +/* +分别遍历两个链表,使用列表存放第一个链表的节点,遍历第二个链表的节点时,如果列表存在该节点,则为相交节点 + */ +public class Solution { + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + List list = new ArrayList<>(); + while (headA != null) { + list.add(headA); + headA = headA.next; + } + while (headB != null) { + if (list.contains(headB)) { + return headB; + } + headB = headB.next; + } + return null; + } +} + + +/* +双指针:使用两个指针都遍历两个链表,由于走的长度一致,最终会在某点相遇,该点就是相交起始结点,如果没相遇则都走到空指针 + */ +public class Solution { + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + if (headA == null || headB == null) { + return null; + } + ListNode A = headA, B = headB; + while (A != B) { + A = A == null ? headB : A.next; + B = B == null ? headA : B.next; + } + return A; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0162.java b/leetcode_Java/Solution0162.java new file mode 100644 index 0000000..6771781 --- /dev/null +++ b/leetcode_Java/Solution0162.java @@ -0,0 +1,60 @@ +// 162. 寻找峰值 + + +/* +二分查找: +1、二分查找的合理性 + 1)对于任意数组而言,一定存在峰值,因为 nums[0] = nums[n] = -∞ + 2)二分不会错过峰值,因为每次分段查找选择更高的一部分,最终的找到的位置其左右相邻值一定比它低 +2、计算中点位置时,(left+right)/2 取整计算,中点位置可能在左边界,一定不可能在右边界,中点位置右边的元素一定存在,所以比较元素时要跟右边元素比较 +3、mid 和 mid+1 位置的元素比较,谁大就以谁为新边界。左元素大就继续到左半部分找、右元素大就到右半部分找。 + + 1 2 3 1 + ↑ ↑ ↑ + l mid r +============ + 1 2 3 1 + ↑ ↑ + l/mid r +============ + 1 2 3 1 + ↑ + l/r + */ +class Solution { + public int findPeakElement(int[] nums) { + int left = 0, right = nums.length - 1; + while (left < right) { + int mid = (left + right) / 2; + if (nums[mid] > nums[mid + 1]) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } +} + + +/* +一次遍历,判断当前位置是否高于左右两边 + */ +class Solution { + public int findPeakElement(int[] nums) { + int n = nums.length; + for (int i = 0; i < n; i++) { + boolean flag = true; + if (i - 1 >= 0 && nums[i - 1] > nums[i]) { + flag = false; + } + if (i + 1 < n && nums[i] < nums[i + 1]) { + flag = false; + } + if (flag) { + return i; + } + } + return -1; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0165.java b/leetcode_Java/Solution0165.java new file mode 100644 index 0000000..1d8bfc3 --- /dev/null +++ b/leetcode_Java/Solution0165.java @@ -0,0 +1,66 @@ +// 165. 比较版本号 + + +/* +双指针: +1、同时遍历两个字符串,直到全部遍历完 +2、双指针分别遍历两个字符串,获取逗号分隔的修订号,将字符转化成数字,比较两个修订号的大小,大于或小于则返回结果1或-1,相同则继续判断下一个修订号, + 遍历结束后仍没有返回,说明修订号全部相同,返回0 + + 12.01.33 12.11.33 + ↑ ↑ ==> 12 = 12 + i j +=================================== + 12.01.33 12.11.33 + ↑ ↑ ==> 1 < 11 + i j + */ +class Solution { + public int compareVersion(String version1, String version2) { + int n1 = version1.length(), n2 = version2.length(); + int i = 0, j = 0; + while (i < n1 || j < n2) { + int num1 = 0, num2 = 0; + while (i < n1 && version1.charAt(i) != '.') { + num1 = num1 * 10 + version1.charAt(i++) - '0'; + } + while (j < n2 && version2.charAt(j) != '.') { + num2 = num2 * 10 + version2.charAt(j++) - '0'; + } + if (num1 > num2) { + return 1; + } else if (num1 < num2) { + return -1; + } + i++; + j++; + } + return 0; + } +} + + +/* +字符串分割:两个字符串根据'.'分割成字符串数组,同时遍历两个数组,把修订号转化成数字,分别比较修订号 + */ +class Solution { + public int compareVersion(String version1, String version2) { + String[] s1 = version1.split("\\."); + String[] s2 = version2.split("\\."); + int n1 = s1.length, n2 = s2.length; + int i = 0, j = 0; + while (i < n1 || j < n2) { + int num1 = 0, num2 = 0; + if (i < n1) { + num1 = Integer.parseInt(s1[i++]); + } + if (j < n2) { + num2 = Integer.parseInt(s2[j++]); + } + if (num1 != num2) { + return num1 > num2 ? 1 : -1; + } + } + return 0; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0169.java b/leetcode_Java/Solution0169.java new file mode 100644 index 0000000..559a24a --- /dev/null +++ b/leetcode_Java/Solution0169.java @@ -0,0 +1,121 @@ +// 169. 多数元素 + + +/* +排序:先排序,不管元素个数是奇数还是偶数,众数元素一定在中间位置 + */ +class Solution { + public int majorityElement(int[] nums) { + Arrays.sort(nums); + return nums[nums.length/2]; + } +} + + +/* +哈希表:使用哈希表存放每个元素的出现次数,遍历哈希表获取出现次数最多的元素 + */ +class Solution { + public int majorityElement(int[] nums) { + HashMap map = new HashMap<>(); + for (int num : nums) { + int count = map.getOrDefault(num, 0); + map.put(num, ++count); + } + int res = nums[0]; + int maxCount = 0; + for (int num : map.keySet()) { + if (map.get(num) > maxCount) { + maxCount = map.get(num); + res = num; + } + } + return res; + } +} + + +/* +投票: +res表示临时众数,count表示该临时众数拥有的票数 +遍历数组,票数为0时,替换上一届的临时众数,将当前元素设为临时众数 +计算票数,如果当前元素与临时众数一样,则投赞成票,否则投反对票 +由于实际众数人多力量大,最后赞成票最多 + */ +class Solution { + public int majorityElement(int[] nums) { + int res = nums[0]; + int count = 0; + for (int num : nums) { + if (count == 0) { + res = num; + } + count += num == res ? 1 : -1; + } + return res; + } +} + + +/* +计数:遍历数组元素,统计该元素出现次数,如果大于一半数组长度,则为众数 + */ +class Solution { + public int majorityElement(int[] nums) { + int maxCount = nums.length / 2; + int res = nums[0]; + for (int num : nums) { + if (count(nums, num) > maxCount) { + res = num; + break; + } + } + return res; + } + + private int count(int[] nums, int num) { + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == num) { + count++; + } + } + return count; + } +} + + +/* +分治:数组对半拆分成多部分,两两统计比较谁出现次数更多,最后得到出现次数最多的众数 + */ +class Solution { + public int majorityElement(int[] nums) { + return majorityElementRec(nums, 0, nums.length - 1); + } + + private int majorityElementRec(int[] nums, int low, int high) { + if (low == high) { + return nums[low]; + } + int mid = (high - low) / 2 + low; + int left = majorityElementRec(nums, low, mid); + int right = majorityElementRec(nums, mid + 1, high); + if (left == right) { + return left; + } + int leftCount = countInRange(nums, left, low, high); + int rightCount = countInRange(nums, right, low, high); + return leftCount > rightCount ? left : right; + } + + private int countInRange(int[] nums, int num, int low, int high) { + int count = 0; + for (int i = low; i <= high; i++) { + if (nums[i] == num) { + count++; + } + } + return count; + } + +} \ No newline at end of file diff --git a/leetcode_Java/Solution0188.java b/leetcode_Java/Solution0188.java new file mode 100644 index 0000000..9486428 --- /dev/null +++ b/leetcode_Java/Solution0188.java @@ -0,0 +1,79 @@ +// 188. 买卖股票的最佳时机 IV + + +/* +动态规划: +1、定义dp数组: + 1)存在三种「状态」:天数、交易次数、是否持有股票,因此定义三维dp + 2)dp[i][j][0] 表示第i天,已经进行了j次交易,不持有股票,获取的最大利润 + dp[i][j][1] 表示第i天,已经进行了j次交易,持有股票,获取的最大利润 +2、初始化: + dp[0][j][0] = 0 表示第0天,不持有股票,任意交易次数,获取的最大利润都为0。创建数组时默认为0,可省略 + dp[0][j][1] = -prices[0] 表示第0天,持有股票,任意交易次数,获取的最大利润都为-prices[0] +3、状态转移方程 + dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]); + 今天不持有股票 前一天不持有股票 前一天持有股票且今天卖出 + dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]); + 今天持有股票 前一天持有股票 前一天不持有股票且今天买入 +4、遍历dp数组填表:第一层遍历天数,第二层遍历交易次数,根据状态转移方程填表。计算当前状态只跟前一天有关,所以两个for循环顺序先后都可以。 +5、返回结果:最后一个状态就是结果。即最后一天,已经进行了k次交易,不持有股票,获取的最大利润 +6、其他细节: + 1)数组至少包含两个元素,即至少有两天才能完成一次交易,否则返回0 + 2)一次交易需要买入和卖出共两天,最大交易次数为数组长度的一半,所以交易次数进行比较取最小值即可 + 3)dp数组定义时k+1,因为交易次数可能为0-k次,或者说计算状态时j-1可能为0,要用到交易次数为0的状态,所以总共有k+1个状态 + 4)[买,卖][买,卖]... 将买入股票时作为一次交易,也就是在买入股票的时候交易次数加1,所以 dp[i - 1][j - 1][0] - prices[i] 买入时前一天的交易次数为j-1,买入后交易次数为j + +三维数组更新过程,左上角表示天数,行表示交易次数,列表示是否持有股票 +k = 2, prices = [3,2,6,5,0,3] +0 1 2 3 4 5 + 0 0 0 0 0 0 0 0 0 0 0 0 + 0 -3 0 -2 4 -2 4 -2 4 0 4 0 + 0 -3 0 -2 0 -2 4 -1 4 4 7 4 + */ +class Solution { + public int maxProfit(int k, int[] prices) { + int n = prices.length; + if (n <= 1) { + return 0; + } + k = Math.min(k, n / 2); + int[][][] dp = new int[n][k + 1][2]; + for (int j = 1; j <= k; j++) { + dp[0][j][0] = 0; + dp[0][j][1] = -prices[0]; + } + for (int i = 1; i < n; i++) { + for (int j = 1; j <= k; j++) { + dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]); + dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]); + } + } + return dp[n - 1][k][0]; + } +} + + +/* +动态规划,状态压缩,去掉天数的维度,交易次数和是否持有股票构成的二维数组变成滚动数组 + */ +class Solution { + public int maxProfit(int k, int[] prices) { + int n = prices.length; + if (n <= 1) { + return 0; + } + k = Math.min(k, n / 2); + int[][] dp = new int[k + 1][2]; + for (int j = 1; j <= k; j++) { + dp[j][0] = 0; + dp[j][1] = -prices[0]; + } + for (int i = 1; i < n; i++) { + for (int j = 1; j <= k; j++) { + dp[j][0] = Math.max(dp[j][0], dp[j][1] + prices[i]); + dp[j][1] = Math.max(dp[j][1], dp[j - 1][0] - prices[i]); + } + } + return dp[k][0]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0198.java b/leetcode_Java/Solution0198.java new file mode 100644 index 0000000..1d91dcd --- /dev/null +++ b/leetcode_Java/Solution0198.java @@ -0,0 +1,50 @@ +// 198. 打家劫舍 + + +/* +动态规划: +1、定义dp数组:dp[i] 表示在第i号房屋时能偷窃到的最高金额 +2、初始化: + 1)dp[0]=0 表示没有偷窃时金额为0,dp[1]=nums[0] 表示第1号房屋时偷窃最高金额为nums[0] + 2)因为状态转移方程由前两项推出,所以要先初始化前两项 +3、状态转移方程: + 1)如果偷窃第i号房屋,那么i-1号房屋不能偷窃,则最高金额为 dp[i - 2] + nums[i - 1] + 2)如果不偷窃第i号房屋,那么最高金额同i-1号房屋一样,即 dp[i - 1] + 3)在 偷窃 和 不偷窃 选择最高金额,即 dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]); +4、遍历dp数组填表:从索引2开始遍历,根据状态转移方程填表 +5、返回结果:最后一个状态就是结果 + */ +class Solution { + public int rob(int[] nums) { + int n = nums.length; + if (n == 0) { + return 0; + } + int[] dp = new int[n + 1]; + dp[1] = nums[0]; + for (int i = 2; i <= n; i++) { + dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]); + } + return dp[n]; + } +} + + +/* +状态压缩:由于dp数组只用到前两项,所以用两个变量替代即可,表示前两个房屋能偷窃到的最高金额,动态更新两个变量的值 + */ +class Solution { + public int rob(int[] nums) { + int n = nums.length; + if (n == 0) { + return 0; + } + int pre = 0, cur = nums[0]; + for (int i = 2; i <= n; i++) { + int temp = cur; + cur = Math.max(cur, pre + nums[i - 1]); + pre = temp; + } + return cur; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0199.java b/leetcode_Java/Solution0199.java new file mode 100644 index 0000000..16ed5d2 --- /dev/null +++ b/leetcode_Java/Solution0199.java @@ -0,0 +1,50 @@ +// 199. 二叉树的右视图 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +102.二叉树的层序遍历,取每层最后一个节点值 + */ +class Solution { + public List rightSideView(TreeNode root) { + List list = new ArrayList<>(); + if (root == null) { + return list; + } + Deque queue = new ArrayDeque<>(); + queue.add(root); + while (!queue.isEmpty()) { + int count = queue.size(); + List sonList = new ArrayList<>(); + while (count > 0) { + TreeNode node = queue.remove(); + sonList.add(node.val); + if (node.left != null) { + queue.add(node.left); + } + if (node.right != null) { + queue.add(node.right); + } + count--; + } + list.add(sonList.get(sonList.size() - 1)); + } + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0200.java b/leetcode_Java/Solution0200.java new file mode 100644 index 0000000..dd65151 --- /dev/null +++ b/leetcode_Java/Solution0200.java @@ -0,0 +1,132 @@ +// 200. 岛屿数量 + + +/* +深度优先搜索: +1、两层for循环遍历二维数组每个位置 +2、当碰到陆地时,通过深度优先搜索往上下左右四个方向扩散陆地,将陆地淹没,并记录岛屿的个数 +3、由于二维数组每个位置都会走过,所以能够找到所有的岛屿 + */ +class Solution { + public int numIslands(char[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == '1') { + res += 1; + dfs(grid, row, col); + } + } + } + return res; + } + + private void dfs(char[][] grid, int row, int col) { + if (row >= 0 && row < grid.length && col >= 0 && col < grid[0].length && grid[row][col] == '1') { + grid[row][col] = '0'; + dfs(grid, row - 1, col); + dfs(grid, row + 1, col); + dfs(grid, row, col - 1); + dfs(grid, row, col + 1); + } + } +} + + +/* +同上。递归函数中,上面方法是通过判断满足条件则执行递归;下面方法是设置终止条件,不满足终止则执行递归。 + */ +class Solution { + public int numIslands(char[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == '1') { + res += 1; + dfs(grid, row, col); + } + } + } + return res; + } + + private void dfs(char[][] grid, int row, int col) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return; + } + if (grid[row][col] == '0') { + return; + } + grid[row][col] = '0'; + dfs(grid, row - 1, col); + dfs(grid, row + 1, col); + dfs(grid, row, col - 1); + dfs(grid, row, col + 1); + } +} + + +/* +同上。创建方向二维数组,遍历递归 + */ +class Solution { + private int[][] direction = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + + public int numIslands(char[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == '1') { + res += 1; + dfs(grid, row, col); + } + } + } + return res; + } + + private void dfs(char[][] grid, int row, int col) { + if (row >= 0 && row < grid.length && col >= 0 && col < grid[0].length && grid[row][col] == '1') { + grid[row][col] = '0'; + for (int[] d : direction) { + dfs(grid, row + d[0], col + d[1]); + } + } + } +} + + +/* +使用额外的二维数组标记访问过的位置,不改动原二维数组 + */ +class Solution { + public int numIslands(char[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + boolean[][] visit = new boolean[n][m]; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == '1' && !visit[row][col]) { + res += 1; + dfs(grid, row, col, visit); + } + } + } + return res; + } + + private void dfs(char[][] grid, int row, int col, boolean[][] visit) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return; + } + if (grid[row][col] == '0' || visit[row][col]) { + return; + } + visit[row][col] = true; + dfs(grid, row - 1, col, visit); + dfs(grid, row + 1, col, visit); + dfs(grid, row, col - 1, visit); + dfs(grid, row, col + 1, visit); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0203.java b/leetcode_Java/Solution0203.java new file mode 100644 index 0000000..19079ee --- /dev/null +++ b/leetcode_Java/Solution0203.java @@ -0,0 +1,54 @@ +// 203. 移除链表元素 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +添加哨兵节点,下一节点有效则指向,无效则跳过 + */ +class Solution { + public ListNode removeElements(ListNode head, int val) { + ListNode root = new ListNode(0, head); + ListNode pre = root; + while (pre.next != null) { + if (pre.next.val == val) { + pre.next = pre.next.next; + } else { + pre = pre.next; + } + } + return root.next; + } +} + + +/* +递归: +1、方法功能:入参是节点和目标值,判断当前节点是否有效,有效则返回当前节点,无效则返回下一节点 +2、终止条件:节点为空时返回空 +3、递归逻辑: + 1)每个节点都需要判断并返回有效节点,因此调用同样的方法 + 2)当前节点的下一节点指针需要指向有效节点,因此调用递归得到的有效节点赋值给该指针 + */ +class Solution { + public ListNode removeElements(ListNode head, int val) { + if (head == null) { + return null; + } + head.next = removeElements(head.next, val); + if (head.val == val) { + return head.next; + } + return head; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0206.java b/leetcode_Java/Solution0206.java new file mode 100644 index 0000000..13c7b17 --- /dev/null +++ b/leetcode_Java/Solution0206.java @@ -0,0 +1,123 @@ +// 206. 反转链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +迭代:使用三个指针分别指向前一个、当前、下一个结点 来定位位置,从头到尾改变链表节点连接的指针方向 + */ +class Solution { + public ListNode reverseList(ListNode head) { + ListNode before = null, after; + while (head != null) { + after = head.next; + head.next = before; + before = head; + head = after; + } + return before; + } +} + + +/* +递归: +1、终止条件:节点为空 或 节点的下一节点为空 +2、方法功能:改变指针方向,返回新的头节点 +3、递归思路: + 1)递归传入下一个节点,目的是为了到达最后一个节点,从尾到头改变链表节点连接的指针方向 + 2)原先 A → B,改变指针方向,变成 A ← B。 即使B指向A,断开A指向B + 3)继续向上一层传递头节点,用于最终返回结果 + */ +class Solution { + public ListNode reverseList(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode root = reverseList(head.next); + head.next.next = head; + head.next = null; + return root; + } +} + + +/* +创建新链表: +1、不改变原链表指针方向,遍历链表节点时,根据节点值创建新的节点,并赋值下一个节点的引用 +2、root表示新链表的头指针,新节点创建完成后,root指针指向新节点,继续创建和连接节点 + */ +class Solution { + public ListNode reverseList(ListNode head) { + ListNode root = null; + for (; head != null; head = head.next) { + root = new ListNode(head.val, root); + } + return root; + } +} + + +/* +逻辑同上,使用while替换for + */ +class Solution { + public ListNode reverseList(ListNode head) { + ListNode root = null; + while (head != null) { + root = new ListNode(head.val, root); + head = head.next; + } + return root; + } +} + + +/* +栈:根据栈后进先出的特点,使用栈存放链表节点,弹出节点时改变节点的下一节点引用 + */ +class Solution { + public ListNode reverseList(ListNode head) { + Stack stack = new Stack<>(); + ListNode root = new ListNode(0); + ListNode temp = root; + while (head != null) { + stack.push(head); + head = head.next; + } + while (!stack.isEmpty()) { + temp.next = stack.pop(); + temp = temp.next; + } + temp.next = null; + return root.next; + } +} + + +/* +插入:遍历节点,将节点拿出来重新构造新的链表,每次节点都插入到新链表的头部,最终实现反转链表 + */ +class Solution { + public ListNode reverseList(ListNode head) { + ListNode root = new ListNode(0); + ListNode temp = head; + while (head != null) { + head = head.next; + temp.next = root.next; + root.next = temp; + temp = head; + } + return root.next; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0207.java b/leetcode_Java/Solution0207.java new file mode 100644 index 0000000..5f65448 --- /dev/null +++ b/leetcode_Java/Solution0207.java @@ -0,0 +1,77 @@ +// 207. 课程表 + + +/* +拓扑排序,广度优先搜索 +1、入度数组 inDegree 记录每门课程的入度 +2、邻接表 adjacent,key为课程号,value为依赖该课程的其他课程号数组 +3、遍历先修课程数组 prerequisites,更新入度数组 inDegree 和邻接表 adjacent +4、队列 queue 存放入度为0的课程号,即没有先修课程,可以选修 +5、从队列弹出课程号,表示该课程已修。然后获取已修课程的后继课程列表 successorList,更新所有后继课程的入度减1。 + 当后继课程入度为0时,则该课程可选修,将课程号存入队列。循环从队列弹出处理,直到没有可选修的课程 +6、遍历入度数组 inDegree,判断所有课程号入度是否为0,不为0则不能修完所有课程,为0则能修完 + +示例:n = 6,先决条件表:[[3, 0], [3, 1], [4, 1], [4, 2], [5, 3], [5, 4]] + 课程 0, 1, 2 没有先修课,可以直接选。其余的课,都有两门先修课。 + 用有向图来展现这种依赖关系(做事情的先后关系),这种叫 有向无环图,把一个 有向无环图 转成 线性的排序 就叫 拓扑排序。 + 拓扑排序是将 有向无环图 所有顶点排成一个线性序列,使得图中任意一对顶点 u 和 v,若边 ∈ E(G),则 u 在线性序列中出现在 v 之前 + 有向图有 入度 和 出度 的概念:如果存在一条有向边 A --> B,则这条边给 A 增加了 1 个出度,给 B 增加了 1 个入度。 + 所以,顶点 0、1、2 的入度为 0,顶点 3、4、5 的入度为 2 +拓扑排序过程: + 1)先统计所有节点的入度 + 2)将入度为0的端点输出,删除该端点和该端点出发的有向边,并将后继端点入度减1 + 3)重复步骤2,如果最后有入度不为0的端点说明存在环,不存在拓扑排序,否则存在拓扑排序 + + 0 + ↘ + 3 + ↗ ↘ + 1 5 拓扑排序:0 1 2 3 4 5 + ↘ ↗ + 4 + ↗ + 2 + */ +class Solution { + public boolean canFinish(int numCourses, int[][] prerequisites) { + Map inDegree = new HashMap<>(); + for (int i = 0; i < numCourses; i++) { + inDegree.put(i, 0); + } + Map> adjacent = new HashMap<>(); + for (int[] relate : prerequisites) { + int cur = relate[1]; + int next = relate[0]; + inDegree.put(next, inDegree.get(next) + 1); + if (!adjacent.containsKey(cur)) { + adjacent.put(cur, new ArrayList<>()); + } + adjacent.get(cur).add(next); + } + Queue queue = new LinkedList<>(); + for (int key : inDegree.keySet()) { + if (inDegree.get(key) == 0) { + queue.offer(key); + } + } + while (!queue.isEmpty()) { + int cur = queue.poll(); + if (!adjacent.containsKey(cur)) { + continue; + } + List successorList = adjacent.get(cur); + for (int next : successorList) { + inDegree.put(next, inDegree.get(next) - 1); + if (inDegree.get(next) == 0) { + queue.offer(next); + } + } + } + for (int key : inDegree.keySet()) { + if (inDegree.get(key) != 0) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0208.java b/leetcode_Java/Solution0208.java new file mode 100644 index 0000000..333680e --- /dev/null +++ b/leetcode_Java/Solution0208.java @@ -0,0 +1,90 @@ +// 208. 实现 Trie (前缀树) + + +/** + * Your Trie object will be instantiated and called as such: + * Trie obj = new Trie(); + * obj.insert(word); + * boolean param_2 = obj.search(word); + * boolean param_3 = obj.startsWith(prefix); + */ + + +/* +前缀树: +1、创建前缀结点内部类 TrieNode + 1)成员变量 isEnd 表示结点是否叶子结点,用于搜索时判断是否搜索结束 + 2)字母映射表 next 保存了对当前结点而言下一个可能出现的所有字符的引用,因此可以通过一个父结点来预知它所有子结点的值 + Trie 中一般都含有大量的空引用,因此在绘制一棵单词查找树时一般会忽略空引用 + 3)构造函数,对成员变量 isEnd、next 赋值初始化 +2、设计前缀树 + 1)成员变量前缀结点 root,作为单词树的入口,方便构造和查找 + 2)构造函数对成员变量root初始化 + 3)插入:向 Trie 中插入一个单词 word + 这个操作和构建链表很像。首先从根结点的子结点开始与 word 第一个字符进行匹配,一直匹配到前缀链上没有对应的字符, + 这时开始不断创建新的结点,直到插入完 word 的最后一个字符,同时还要标记最后一个结点 isEnd=true,表示它是一个单词的末尾 + 4)单词查找:查找 Trie 中是否存在单词 word + 从根结点的子结点开始,一直向下匹配,如果出现结点值为空就返回 false,如果匹配到了最后一个字符,再判断结点是否单词末尾返回是否存在单词 + 5)前缀查找:判断 Trie 中是否有以 prefix 为前缀的单词 + 和 search 操作类似,但只要匹配到最后一个字符,就说明存在该前缀的单词 + +sea、sell、she + s + / \ + e h + / \ | + a l e + | + l + */ +class Trie { + + class TrieNode { + private boolean isEnd; + private TrieNode[] next; + + public TrieNode() { + isEnd = false; + next = new TrieNode[26]; + } + } + + private TrieNode root; + + public Trie() { + root = new TrieNode(); + } + + public void insert(String word) { + TrieNode node = root; + for (char c : word.toCharArray()) { + if (node.next[c - 'a'] == null) { + node.next[c - 'a'] = new TrieNode(); + } + node = node.next[c - 'a']; + } + node.isEnd = true; + } + + public boolean search(String word) { + TrieNode node = root; + for (char c : word.toCharArray()) { + node = node.next[c - 'a']; + if (node == null) { + return false; + } + } + return node.isEnd; + } + + public boolean startsWith(String prefix) { + TrieNode node = root; + for (char c : prefix.toCharArray()) { + node = node.next[c - 'a']; + if (node == null) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0215.java b/leetcode_Java/Solution0215.java new file mode 100644 index 0000000..5efb960 --- /dev/null +++ b/leetcode_Java/Solution0215.java @@ -0,0 +1,112 @@ +// 215. 数组中的第K个最大元素 +// 主要思路同“347. 前 K 个高频元素” + +/* +排序后取倒数第k个元素,api使用快速排序 + */ +class Solution { + public int findKthLargest(int[] nums, int k) { + Arrays.sort(nums); + return nums[nums.length - k]; + } +} + + +// 具体见“十大排序算法_Java” + +/* +快速排序: +1、一次排序操作将返回一个已经排好位置的中点索引mid,该索引左边的元素都小于它,右边的元素都大于等于它 +2、找第K个最大元素不用整个数组都排序,将中点索引mid与目标索引target比较,直接返回结果 或 选择递归左或右半部分继续排序 +3、递归方法: + 1)方法功能:根据数组、指定左右边界、目标值,进行一次排序,获取排序后的中点索引与目标索引比较,相等则返回目标值 + 2)终止条件:左边界等于右边界,说明只剩一个元素,不用排序,直接返回该元素 + 由于k在数组长度范围内,目标值一定存在,每次选择有效区间,mid每次加减1,所以不存在左边界大于右边界的情况 + 3)递归逻辑:未找到目标值之前,排序好的中点的左半部分或右半部分数组也需要同样的操作寻找目标值,调用同样的方法进行排序,并接收递归方法返回值,最后返回结果 + */ +class Solution { + public int findKthLargest(int[] nums, int k) { + int n = nums.length; + return mainSort(nums, 0, n - 1, n - k); + } + + // 递归方法 + private int mainSort(int[] nums, int left, int right, int target) { + if (left == right) { + return nums[left]; + } + int res; + int mid = partition(nums, left, right); + if (mid == target) { + res = nums[target]; + } else if (mid > target) { + res = mainSort(nums, left, mid - 1, target); + } else { + res = mainSort(nums, mid + 1, right, target); + } + return res; + } + + // 一次排序操作 + private int partition(int[] nums, int left, int right) { + int index = left + 1; + for (int i = index; i <= right; i++) { + if (nums[i] < nums[left]) { + swap(nums, i, index); + index++; + } + } + swap(nums, left, index - 1); + return index - 1; + } + + // 交换元素 + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} + + +/* +最大堆排序: +1、先将普通数组调整成最大堆数组 +2、堆顶元素就是最大值,将堆顶元素交换到数组尾部,重新调整剩余数组元素为最大堆 +3、循环处理第2步,最终数组升序排序 +4、找第K个最大元素不用整个数组都排序,每次调整都会将剩余数组最大值交换到数组尾部,记录交换次数,直到第K个最大元素时直接返回结果 + */ +class Solution { + public int findKthLargest(int[] nums, int k) { + int n = nums.length; + for (int i = n / 2 - 1; i >= 0; i--) { + maxHeapify(nums, i, n); + } + while (n > 0 && k > 0) { + swap(nums, 0, n - 1); + n--; + k--; + maxHeapify(nums, 0, n); + } + return nums[n]; + } + + private void maxHeapify(int[] nums, int root, int n) { + int maxIndex = root; + int left = root * 2 + 1, right = root * 2 + 2; + if (left < n && nums[left] > nums[maxIndex]) + maxIndex = left; + if (right < n && nums[right] > nums[maxIndex]) + maxIndex = right; + if (maxIndex != root) { + swap(nums, maxIndex, root); + maxHeapify(nums, maxIndex, n); + } + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0216.java b/leetcode_Java/Solution0216.java new file mode 100644 index 0000000..3426c5b --- /dev/null +++ b/leetcode_Java/Solution0216.java @@ -0,0 +1,39 @@ +// 216. 组合总和 III + + +/* +回溯思路: +1、画n叉树 +2、开始套模板,定义全局变量全部结果res、子结果track,调用回溯方法处理,返回结果 +3、定义递归函数 + 1)分析方法参数,需要index控制下一层区间 + 2)终止条件,个数满足,判断子结果和,收集子结果 + 3)做选择,加入子结果 + 4)递归,开启下一层for循环 + 5)回溯,撤销选择 + 6)优化,剪枝条件,过滤无效遍历 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedLast<>(); + + public List> combinationSum3(int k, int n) { + backtrack(k, n, 1); + return res; + } + + private void backtrack(int k, int n, int startIndex) { + if (k == 0) { + int sum = track.stream().mapToInt(x -> x).sum(); + if (sum == n) { + res.add(new ArrayList<>(track)); + } + return; + } + for (int i = startIndex; i <= 9 - k + 1; i++) { + track.addLast(i); + backtrack(k - 1, n, i + 1); + track.removeLast(); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0221.java b/leetcode_Java/Solution0221.java new file mode 100644 index 0000000..b8ce989 --- /dev/null +++ b/leetcode_Java/Solution0221.java @@ -0,0 +1,39 @@ +// 221. 最大正方形 + + +/* +动态规划: +1、定义dp数组:dp[row][col] 表示以 matrix[row-1][col-1] 为右下角的正方形的最大边长 +2、初始化:由于状态转移方程要用到上一行和上一列,所以二维dp数组扩容首行首列,初始化为0 +3、状态转移方程: + 若某格子值为 1,则以此为右下角的正方形的最大边长为 左面的正方形、上面的正方形、左上的正方形 的最小边长加1 + 左、上、左上取最小边长,是因为木桶原理,只能取最小才能构成正方形,其他两个边长肯定大于等于最小边长,三个正方形加上当前格子,就能构成新的边长为 最小边长加1 的正方形 +4、遍历dp数组填表:两个for循环遍历二维dp数组,当格子为1时,根据状态转移方程填表 +5、返回结果:边计算边保留最大边长,最后返回面积 + +以最后一个为例: + matrix dp +1 1 1 1 1 1 1 1 +1 1 1 1 1 2 2 2 +1 1 1 1 ==> 1 2 3 3 ==> dp[3][3] = min(2, 3, 3) + 1 +0 1 1 1 0 1 2 3 + */ +class Solution { + public int maximalSquare(char[][] matrix) { + int m = matrix.length, n = matrix[0].length; + if (m < 1 || n < 1) { + return 0; + } + int maxSide = 0; + int[][] dp = new int[m + 1][n + 1]; + for (int row = 1; row <= m; row++) { + for (int col = 1; col <= n; col++) { + if (matrix[row - 1][col - 1] == '1') { + dp[row][col] = Math.min(dp[row - 1][col - 1], Math.min(dp[row - 1][col], dp[row][col - 1])) + 1; + maxSide = Math.max(maxSide, dp[row][col]); + } + } + } + return maxSide * maxSide; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0224.java b/leetcode_Java/Solution0224.java new file mode 100644 index 0000000..9f5342d --- /dev/null +++ b/leetcode_Java/Solution0224.java @@ -0,0 +1,130 @@ +// 224. 基本计算器 + + +/* +双栈: +1、使用两个栈,numsStack 存放数字,opsStack 存放操作符 +2、预处理: + 1)由于第一个数可能是负数,为了减少边界判断,先往 numsStack 添加一个 0 + 2)输入中不存在两个连续的操作符,为防止 () 内出现的首个字符为运算符,将所有空格去掉,将 (- 替换为 (0- ,(+ 替换为 (0+ +3、遍历字符串中的字符 + 1)遇到 ( 时,则存入操作符栈 + 2)遇到 ) 时, + ① 当操作符栈 不为空 且 栈顶不是左括号时,取出两个数字和操作符进行计算,并将计算结果存入数字栈 + ② 直到遇到左括号,从操作符栈 出栈 + 3)遇到数字时,继续遍历获取连续的数字,并将字符串转化成整型类型数字,最后数字存入数字栈 + 4)遇到操作符 +、- 时, + ① 如果前一字符是左括号,要先将0存入数字栈,表示 (0- 或 (0+ ,才能进行计算 + ② 当操作符栈 不为空 且 栈顶不是左括号时,取出两个数字和操作符进行计算,并将计算结果存入数字栈 + ③ 将当前操作符存入 操作符栈 +4、操作符栈仍不为空时,取出两个数字和操作符进行计算,并将计算结果存入数字栈,最终返回数字栈顶值 +5、计算的时机: + 1)当前字符为 ) ,操作符栈顶字符为 (,说明括号内的数字计算完了,可以结束了 + 当前字符为 +、- ,操作符栈顶字符为 (,说明括号内的数字只有一个,还不能计算 + 所以遇到 )、+、- 时,操作符栈 不为空 且 栈顶不是 ( 时才能计算 + 2)遇到 )、+、- 时,才会计算前一操作符的结果,然后将 (出操作符栈 或 +、-入操作符栈 + 3)字符串遍历完后,操作符栈会不为空,因为 遇到新的操作符才会计算旧的操作符 和 受到(的限制 导致前面的没有计算,但只剩 +、-,所以可以直接计算 + */ +class Solution { + public int calculate(String s) { + Deque opsStack = new ArrayDeque<>(); + Deque numsStack = new ArrayDeque<>(); + numsStack.push(0); + s = s.replaceAll(" ", ""); + int n = s.length(); + char[] charArray = s.toCharArray(); + for (int i = 0; i < n; i++) { + char c = charArray[i]; + if (c == '(') { + opsStack.push(c); + } else if (c == ')') { + while (!opsStack.isEmpty() && opsStack.peek() != '(') { + cal(numsStack, opsStack); + } + opsStack.pop(); + } else if (Character.isDigit(c)) { + int j = i, num = 0; + while (j < n && Character.isDigit(charArray[j])) { + num = num * 10 + charArray[j++] - '0'; + } + numsStack.push(num); + i = j - 1; + } else { + if (i > 0 && charArray[i - 1] == '(') { + numsStack.push(0); + } + while (!opsStack.isEmpty() && opsStack.peek() != '(') { + cal(numsStack, opsStack); + } + opsStack.push(c); + } + } + while (!opsStack.isEmpty()) { + cal(numsStack, opsStack); + } + return numsStack.peek(); + } + + private void cal(Deque numsStack, Deque opsStack) { + if (numsStack.isEmpty() || numsStack.size() < 2 || opsStack.isEmpty()) { + return; + } + int b = numsStack.pop(), a = numsStack.pop(); + char op = opsStack.pop(); + numsStack.push(op == '+' ? a + b : a - b); + } +} + + +/* +ArrayDeque使用不同的api + */ +class Solution { + public int calculate(String s) { + Deque opsQueue = new ArrayDeque<>(); + Deque numsQueue = new ArrayDeque<>(); + numsQueue.addLast(0); + s = s.replaceAll(" ", ""); + int n = s.length(); + char[] charArray = s.toCharArray(); + for (int i = 0; i < n; i++) { + char c = charArray[i]; + if (c == '(') { + opsQueue.addLast(c); + } else if (c == ')') { + while (!opsQueue.isEmpty() && opsQueue.peekLast() != '(') { + cal(numsQueue, opsQueue); + } + opsQueue.pollLast(); + } else if (Character.isDigit(c)) { + int j = i, num = 0; + while (j < n && Character.isDigit(charArray[j])) { + num = num * 10 + charArray[j++] - '0'; + } + numsQueue.addLast(num); + i = j - 1; + } else { + if (i > 0 && charArray[i - 1] == '(') { + numsQueue.addLast(0); + } + while (!opsQueue.isEmpty() && opsQueue.peekLast() != '(') { + cal(numsQueue, opsQueue); + } + opsQueue.addLast(c); + } + } + while (!opsQueue.isEmpty()) { + cal(numsQueue, opsQueue); + } + return numsQueue.peekLast(); + } + + private void cal(Deque numsQueue, Deque opsQueue) { + if (numsQueue.isEmpty() || numsQueue.size() < 2 || opsQueue.isEmpty()) { + return; + } + int b = numsQueue.pollLast(), a = numsQueue.pollLast(); + char op = opsQueue.pollLast(); + numsQueue.addLast(op == '+' ? a + b : a - b); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0226.java b/leetcode_Java/Solution0226.java new file mode 100644 index 0000000..6f171a4 --- /dev/null +++ b/leetcode_Java/Solution0226.java @@ -0,0 +1,89 @@ +// 226. 翻转二叉树 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、方法功能:节点为空时返回空,节点不为空时把节点的左右子节点交换一下 +2、递归逻辑: + 1)每一层,每个节点,都需要将其左右子节点交换,就需要调用同个方法 + 2)方法功能是交换节点,不需要接收下一层的返回值给上一层使用 + 3)所有节点都交换完成后,返回根节点 +========================================================= +新模板注释,递归 +1、方法功能:入参是一个节点,将该节点的左右子节点交换,返回该节点 +2、终止条件:节点为空时返回空 +3、一个节点处理过程和返回结果:将该节点的左右子节点交换,返回该节点 +4、递归调用:左右节点的子节点同样需要交换,因此调用同样的方法递归处理 +5、递归顺序:前序遍历,先把根节点的子节点交换完,从上往下按序进行交换 +6、使用递归调用结果和返回结果:不用接收调用结果,处理交换即可,最后返回根节点 +* */ +class Solution { + public TreeNode invertTree(TreeNode root) { + if (root == null) { + return null; + } + TreeNode tempNode = root.left; + root.left = root.right; + root.right = tempNode; + invertTree(root.left); + invertTree(root.right); + return root; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:栈存放要交换其左右子节点的节点 +* 2、保留根节点指针:根节点指针赋值给新节点指针,使用新节点指针遍历节点,最终需要返回根节点指针 +* (实例对象存储在堆内存中,对象变量存储在栈中,对象变量就是一个引用,也表示指针,对象变量的赋值就是指针指向的改变) +* 3、栈初始化:将新节点存入栈 +* 4、迭代逻辑: +* 1)弹出节点,判断节点的左右子节点是否都为空,为空则跳过 +* 2)左右子节点不都为空,则进行节点交换 +* 3)然后将不为空的节点存入栈中 +* 4)遍历了所有节点且交换了其左右子节点,则翻转二叉树完成,返回根节点 +* */ +class Solution { + public TreeNode invertTree(TreeNode root) { + if (root == null) { + return null; + } + Stack stack = new Stack<>(); + TreeNode curNode = root; + stack.push(curNode); + while (!stack.isEmpty()) { + curNode = stack.pop(); + if (curNode.left == null && curNode.right == null) { + continue; + } + TreeNode tempNode = curNode.left; + curNode.left = curNode.right; + curNode.right = tempNode; + if (curNode.left != null) { + stack.push(curNode.left); + } + if (curNode.right != null) { + stack.push(curNode.right); + } + } + return root; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0227.java b/leetcode_Java/Solution0227.java new file mode 100644 index 0000000..159b57d --- /dev/null +++ b/leetcode_Java/Solution0227.java @@ -0,0 +1,80 @@ +// 227. 基本计算器 II + + +/* +在“224. 基本计算器”的基础上进阶 +1、支持 + - * / ^ % ( ) 的完全表达式问题 +2、用map存放运算符的优先级,只有「栈内运算符」比「当前运算符」优先级高或同等,才能进行运算 + */ +class Solution { + Map map = new HashMap<>(){{ + put('+', 1); + put('-', 1); + put('*', 2); + put('/', 2); + put('%', 2); + put('^', 3); + }}; + + public int calculate(String s) { + Deque opsStack = new ArrayDeque<>(); + Deque numsStack = new ArrayDeque<>(); + numsStack.push(0); + s = s.replaceAll(" ", ""); + int n = s.length(); + char[] charArray = s.toCharArray(); + for (int i = 0; i < n; i++) { + char c = charArray[i]; + if (c == '(') { + opsStack.push(c); + } else if (c == ')') { + while (!opsStack.isEmpty() && opsStack.peek() != '(') { + cal(numsStack, opsStack); + } + opsStack.pop(); + } else if (Character.isDigit(c)) { + int j = i, num = 0; + while (j < n && Character.isDigit(charArray[j])) { + num = num * 10 + charArray[j++] - '0'; + } + numsStack.push(num); + i = j - 1; + } else { + if (i > 0 && charArray[i - 1] == '(') { + numsStack.push(0); + } + while (!opsStack.isEmpty() && opsStack.peek() != '(' && map.get(opsStack.peek()) >= map.get(c)) { + cal(numsStack, opsStack); + } + opsStack.push(c); + } + } + while (!opsStack.isEmpty()) { + cal(numsStack, opsStack); + } + return numsStack.peek(); + } + + private void cal(Deque numsStack, Deque opsStack) { + if (numsStack.isEmpty() || numsStack.size() < 2 || opsStack.isEmpty()) { + return; + } + int b = numsStack.pop(), a = numsStack.pop(); + char op = opsStack.pop(); + int res = 0; + if (op == '+') { + res = a + b; + } else if (op == '-') { + res = a - b; + } else if (op == '*') { + res = a * b; + } else if (op == '/') { + res = a / b; + } else if (op == '%') { + res = a % b; + } else if (op == '^') { + res = (int) Math.pow(a, b); + } + numsStack.push(res); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0232.java b/leetcode_Java/Solution0232.java new file mode 100644 index 0000000..5cf6adf --- /dev/null +++ b/leetcode_Java/Solution0232.java @@ -0,0 +1,98 @@ +// 232. 用栈实现队列 + + +/** + * Your MyQueue object will be instantiated and called as such: + * MyQueue obj = new MyQueue(); + * obj.push(x); + * int param_2 = obj.pop(); + * int param_3 = obj.peek(); + * boolean param_4 = obj.empty(); + */ + + +/* +1、stack1作为队列,元素正序。stack2作为辅助工具,不存放元素 +2、push:先把stack1倒入stack2,元素压入stack1,再把stack2倒入stack1。实现了新元素在栈底,且整体正序 +3、pop:直接弹出stack1栈顶 +4、peek:直接查看stack1栈顶 +5、empty:直接判断stack1是否为空 + */ +class MyQueue { + private Stack stack1; + private Stack stack2; + + public MyQueue() { + stack1 = new Stack<>(); + stack2 = new Stack<>(); + } + + public void push(int x) { + while (!stack1.isEmpty()) { + stack2.push(stack1.pop()); + } + stack1.push(x); + while (!stack2.isEmpty()) { + stack1.push(stack2.pop()); + } + } + + public int pop() { + return stack1.pop(); + } + + public int peek() { + return stack1.peek(); + } + + public boolean empty() { + return stack1.isEmpty(); + } +} + + +/* +1、stack1作为栈,元素倒序。stack2作为队列,元素正序 +2、push:入栈就入stack1。push时如果stack1为空,记录队首元素,再入栈。队首元素用于peek时直接返回 +3、pop:出栈就出stack2。stack2如果为空就把stack1倒入stack2,stack2不为空就弹出栈顶 +4、peek:查看队首元素。stack2不为空那么栈顶就是队首,stack2为空那么就返回stack1记录的栈底队首元素 +5、empty:stack1和stack2都为空时则空 + */ +class MyQueue { + private Stack stack1; + private Stack stack2; + private int head; + + public MyQueue() { + stack1 = new Stack<>(); + stack2 = new Stack<>(); + } + + public void push(int x) { + if (stack1.isEmpty()) { + head = x; + } + stack1.push(x); + } + + public int pop() { + if (stack2.isEmpty()) { + while (!stack1.isEmpty()) { + stack2.push(stack1.pop()); + } + } + return stack2.pop(); + } + + public int peek() { + if (!stack2.isEmpty()) { + return stack2.peek(); + } + return head; + } + + public boolean empty() { + return stack1.isEmpty() && stack2.isEmpty(); + } +} + diff --git a/leetcode_Java/Solution0234.java b/leetcode_Java/Solution0234.java new file mode 100644 index 0000000..a486bfc --- /dev/null +++ b/leetcode_Java/Solution0234.java @@ -0,0 +1,98 @@ +// 234. 回文链表 + + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ + + +/* +节点值存入列表,双指针从首尾到中间移动判断元素是否对称一样 + */ +class Solution { + public boolean isPalindrome(ListNode head) { + List list = new ArrayList<>(); + while (head != null) { + list.add(head.val); + head = head.next; + } + int l = 0, r = list.size() - 1; + while (l < r) { + if (list.get(l++) != list.get(r--)) { + return false; + } + } + return true; + } +} + + +/* +递归: +1、通过递归实现在链表上双指针判断首尾元素是否一样 +2、使用成员变量作为头部指针,该指针不受递归影响,每次判断完向后移动一步 +3、通过递归直接到达链表尾部指针,此时通过首尾指针判断元素是否一样,下一层递归结束后返回上一层,相当于尾部指针往前移动一步 +4、先判断上一层处理结果元素是否一样,是的话再判断当前层元素是否一样 + */ +class Solution { + private ListNode left; + + public boolean isPalindrome(ListNode head) { + left = head; + return recursivelyCheck(head); + } + + private boolean recursivelyCheck(ListNode right) { + if (right == null) { + return true; + } + if (!recursivelyCheck(right.next)) { + return false; + } + if (right.val != left.val) { + return false; + } + left = left.next; + return true; + } +} + + +/* +快指针走到末尾,慢指针刚好到中间,其中慢指针将前半部分反转,然后从中间到首尾比较 +原始:1 → 2 → 3 → 4 → 3 → 2 → 1 +反转:1 ← 2 ← 3 ← 4 → 3 → 2 → 1 + */ +class Solution { + public boolean isPalindrome(ListNode head) { + if (head == null || head.next == null) { + return true; + } + ListNode slow = head, fast = head, pre = null, temp; + while (fast != null && fast.next != null) { + fast = fast.next.next; + temp = slow.next; + slow.next = pre; + pre = slow; + slow = temp; + } + if (fast != null) { + slow = slow.next; + } + while (pre != null && slow != null) { + if (pre.val != slow.val) { + return false; + } + pre = pre.next; + slow = slow.next; + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0236.java b/leetcode_Java/Solution0236.java new file mode 100644 index 0000000..8e7063d --- /dev/null +++ b/leetcode_Java/Solution0236.java @@ -0,0 +1,78 @@ +// 236. 二叉树的最近公共祖先 + + +/** + * class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + + +/* +递归: +1、若root是p,q的最近公共祖先,那么有三种情况,即 p <= root <= q 或 q <= root <= p + 1)p、q分别在root的左右子树上 + 2)p=root,且q在root的左或右子树上 + 3)q=root,且p在root的左或右子树上 +2、函数功能:在节点中找p、q,找不到返回null,找到了返回该节点 不继续往下找了。即第一个if语句就代表函数最基本的功能。 +3、递归逻辑: + 1)根节点找不到时,要再判断左右节点能否找到,因此调用递归函数得到左右节点寻找结果 + 2)拿结果做判断,如果左右都能找到,说明p、q在左右两边,当前根节点是最近公共祖先,返回根节点 + 3)如果左边找到了,右边没找到,说明p、q都在左边,左边的节点是最近公共祖先 + 如果右边找到了,左边没找到,说明p、q都在右边,右边的节点是最近公共祖先 + + root p q + / \ / \ / \ + p q x q x p + p q + / \ / \ + q x p x +==================================================================================================== +新模板注释,递归 +1、方法功能:入参是一个根节点、两个目标节点,寻找与目标节点相同的节点,存在则返回该节点,不存在则返回空 +2、终止条件:节点为空时,返回空 +3、一个节点处理过程和返回结果:节点等于其中一个目标节点时,返回该节点,否则返回空 +4、递归调用:左右节点同样需要寻找目标节点,因此调用同样的方法处理,获取结果 +5、递归顺序:前序遍历,当前节点处理后能找到则返回,找不到再继续从左右节点找 +6、使用递归调用结果和返回结果: + 1)左节点找到 且 右节点找到,那么最近公共祖先是根节点 + 2)左节点 或 右节点 只有一个找到,那么最近公共祖先是 左节点 或 右节点 + */ +public class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) { + return root; + } + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + if (left != null && right != null) { + return root; + } + return left != null ? left : right; + } +} + +/* +上面解法的单节点处理逻辑 + */ +class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) { + return null; + } + if (root == p || root == q) { + return root; + } + return null; + } + + // 再简化 + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) { + return root; + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0238.java b/leetcode_Java/Solution0238.java new file mode 100644 index 0000000..534fe8e --- /dev/null +++ b/leetcode_Java/Solution0238.java @@ -0,0 +1,29 @@ +// 238. 除自身以外数组的乘积 + + +/* +前缀和: +1、当前数 = 左边的乘积 x 右边的乘积 +2、初始化结果数组为1,方便乘积时保留左右部分的值 +3、遍历数组,从左到右计算时,当前位置的值为左部分的乘积;从右到左计算时,当前位置的值为右部分的乘积; + 两次计算都没有将当前位置的值加入乘积,最终当前位置的值就是 左边的乘积 x 右边的乘积 + +nums 5 2 3 4 +res 1 1 1 1 +l 1 5 5*2 5*2*3 +r 4*3*2 4*3 4 1 + */ +class Solution { + public int[] productExceptSelf(int[] nums) { + int l = 1, r = 1, n = nums.length; + int[] res = new int[n]; + Arrays.fill(res, 1); + for (int i = 0; i < n; i++) { + res[i] *= l; + l *= nums[i]; + res[n - i - 1] *= r; + r *= nums[n - i - 1]; + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0239.java b/leetcode_Java/Solution0239.java new file mode 100644 index 0000000..cc5bb5c --- /dev/null +++ b/leetcode_Java/Solution0239.java @@ -0,0 +1,34 @@ +// 239. 滑动窗口最大值 + + +/* +剑指offer 64.滑动窗口的最大值 +双端队列,单调递减队列: +1、根据数组长度和窗口大小,初始化结果数组长度 +2、队列存放的是索引,既能通过索引判断是否在窗口内,也能通过索引获取元素值 +3、遍历数组元素 + 1)当队列不为空 且 当前元素大于等于队尾元素,则弹出队尾元素,循环处理 + 2)当前元素加入队尾。此时队列是单调递减队列 + 3)检查队首索引是否在窗口内,不在窗口内则弹出队首索引 + 4)当前滑动窗口大小为k时,队首索引的元素是窗口内的最大值,加入结果数组 + */ +class Solution { + public int[] maxSlidingWindow(int[] nums, int k) { + int n = nums.length; + int[] res = new int[n - k + 1]; + Deque queue = new ArrayDeque<>(); + for (int i = 0; i < n; i++) { + while (!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]) { + queue.pollLast(); + } + queue.addLast(i); + if (queue.peek() == i - k) { + queue.poll(); + } + if (i + 1 >= k) { + res[i + 1 - k] = nums[queue.peek()]; + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0240.java b/leetcode_Java/Solution0240.java new file mode 100644 index 0000000..e2ea57c --- /dev/null +++ b/leetcode_Java/Solution0240.java @@ -0,0 +1,24 @@ +// 240. 搜索二维矩阵 II + + +/* +二分查找: +1、从左下角开始,在有效边界范围内,元素小于目标值则右移,元素大于目标值则上移 +2、如果找到了目标值则返回true,遍历结束后没找到目标值则返回false + */ +class Solution { + public boolean searchMatrix(int[][] matrix, int target) { + int m = matrix.length, n = matrix[0].length; + int row = m - 1, col = 0; + while (row >= 0 && col < n) { + if (matrix[row][col] == target) { + return true; + } else if (matrix[row][col] < target) { + col++; + } else { + row--; + } + } + return false; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0279.java b/leetcode_Java/Solution0279.java new file mode 100644 index 0000000..da552a2 --- /dev/null +++ b/leetcode_Java/Solution0279.java @@ -0,0 +1,29 @@ +// 279. 完全平方数 + + +/* +动态规划: +1、题目:给你一个整数 n,返回 和为n 的完全平方数的最少数量。完全平方数是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。 +2、题目简化:求和为n的完全平方数的最少数量 +3、定义dp数组:dp[i]表示和为i的完全平方数的最少数量 +4、初始化: + 1)一维dp数组扩容:增加和为0这一最小规模的情况 + 2)dp[i] = i,表示最坏情况全部由1相加,数量为i +5、状态转移方程:dp[i] = Math.min(dp[i], dp[i - j * j] + 1); + 1)j*j 是一个完全平方数,i-j*j 表示减去一个完全平方数的值,dp[i-j*j] 表示和为 i-j*j 完全平方数的最少数量,dp[i-j*j] + 1 表示和为i的完全平方数的数量 + 2)构成i有多个完全平方数相加,所以遍历j,每次减去一个j*j的完全平方数,由旧状态加1直接得到当前值数量,比较得到最少数量 +6、遍历dp数组填表:一个for循环遍历dp数组的未知位置,另一个for循环遍历完全平方数,根据条件获取dp数组的已知位置,根据状态转移方程取已知结果汇总计算未知结果 +7、返回结果:最后一个状态就是结果 + */ +class Solution { + public int numSquares(int n) { + int[] dp = new int[n + 1]; + for (int i = 1; i <= n; i++) { + dp[i] = i; + for (int j = 1; j * j <= i; j++) { + dp[i] = Math.min(dp[i], dp[i - j * j] + 1); + } + } + return dp[n]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0283.java b/leetcode_Java/Solution0283.java new file mode 100644 index 0000000..fafcbf1 --- /dev/null +++ b/leetcode_Java/Solution0283.java @@ -0,0 +1,60 @@ +// 283. 移动零 + + +/* +双指针,交换元素: +1、左右指针都从起点开始 +2、右指针用于遍历整个数组,遇到零则跳过,遇到非零元素时则与左指针的元素交换,右指针每遍历完一个元素就向右移动一步 +3、左指针只有当交换元素后才向右移动一步,保证左指针走过的位置都是非零元素 + */ +class Solution { + public void moveZeroes(int[] nums) { + int left = 0, right = 0, n = nums.length; + while (right < n) { + if (nums[right] != 0) { + int temp = nums[left]; + nums[left] = nums[right]; + nums[right] = temp; + left++; + } + right++; + } + } +} + + +/* +覆盖元素,后面补0:同样是双指针思路,比直接交换元素多了补0的操作 + */ +class Solution { + public void moveZeroes(int[] nums) { + int left = 0, right = 0, n = nums.length; + while (right < n) { + if (nums[right] != 0) { + nums[left++] = nums[right]; + } + right++; + } + while (left < n) { + nums[left++] = 0; + } + } +} + + +/* +逻辑同上,用for替代while + */ +class Solution { + public void moveZeroes(int[] nums) { + int left = 0, right = 0, n = nums.length; + for (; right < n; right++) { + if (nums[right] != 0) { + nums[left++] = nums[right]; + } + } + for (; left < n; left++) { + nums[left] = 0; + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0287.java b/leetcode_Java/Solution0287.java new file mode 100644 index 0000000..cea47d4 --- /dev/null +++ b/leetcode_Java/Solution0287.java @@ -0,0 +1,143 @@ +// 287. 寻找重复数 + + +/* +哈希表:记录遍历过的数,如果当前数已存在于哈希表中,则该数是重复数 + */ +class Solution { + public int findDuplicate(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + if (map.getOrDefault(num, false)) { + return num; + } + map.put(num, true); + } + return -1; + } +} + + +/* +快慢指针,思路同“142.环形链表II” +1、如果数组中有重复的数,以数组 [1,3,4,2,2] 为例,我们将数组索引 n 和数 nums[n] 建立一个映射关系 f(n),其映射关系 n->f(n) 为: + 元素: 1 3 4 2 2 + 索引: 0 1 2 3 4 + 0->1 1->3 2->4 3->2 4->2 +2、我们从索引为 0 出发,根据 f(n) 计算出一个值,以这个值为新的索引,再用这个函数计算,以此类推产生一个类似链表一样的索引序列 + 0 → 1 → 3 → 2 → 4 + ↑_____↓ +3、将问题转化成环形链表 + 1)数组中有一个重复的整数 <==> 链表中存在环 + 2)找到数组中的重复整数 <==> 找到链表的环入口 +4、快慢指针走法 + 1)慢指针走一步 slow = slow.next <==> slow = nums[slow] + 2)快指针走两步 fast = fast.next.next <==> fast = nums[nums[fast]] + */ +class Solution { + public int findDuplicate(int[] nums) { + int slow = 0, fast = 0; + do { + slow = nums[slow]; + fast = nums[nums[fast]]; + } while (slow != fast); + int pre = 0; + while (slow != pre) { + slow = nums[slow]; + pre = nums[pre]; + } + return slow; + } +} + + +/* +二分查找: +1、数字在[1,n]范围内,初始化left为1,right为n。所有计算都是用数字,没用到索引 +2、找中间数mid,计算数组中小于等于mid的元素数量,如果数量大于mid说明重复元素在区间[left,mid],否则重复元素在区间[mid+1,right] +3、循环二分查找,直到找到重复元素 + +数组:[1,3,2,5,2,4] + 1 2 3 4 5 +left mid right +count=4 > mid=3 +====================== + 1 2 3 4 5 +left mid right +count=3 > mid=2 +====================== + 1 2 3 4 5 +left/mid right +count=1 !> mid=1 +====================== + 1 2 3 4 5 + left/right + */ +class Solution { + public int findDuplicate(int[] nums) { + int left = 1, right = nums.length - 1; + while (left < right) { + int mid = (left + right) / 2; + int count = 0; + for (int num : nums) { + if (num <= mid) { + count++; + } + } + if (count > mid) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } +} + + +/* +位运算:将 原数组 与 [1,n]数字 转化成二进制后,统计对应每一位1的个数,原数组比范围数组 位上多出来的1 是重复元素位上的1,找到重复元素所有位上的1后 转化得到重复元素值 +nums = [1,3,4,2,2] + +1 3 4 2 2 写成二进制 + 1 [0 0 1] + 3 [0 1 1] + 4 [1 0 0] + 2 [0 1 0] + 2 [0 1 0] + x 1 3 2 + +把 1 到 n,也就是 1 2 3 4 也写成二进制 + 1 [0 0 1] + 2 [0 1 0] + 3 [0 1 1] + 4 [1 0 0] + y 1 2 2 + +res 0 1 0 + */ +class Solution { + public int findDuplicate(int[] nums) { + int res = 0, n = nums.length; + int maxBit = 31; + while (((n - 1) >> maxBit) == 0) { + maxBit--; + } + for (int i = 0; i <= maxBit; i++) { + int x = 0, y = 0; + int mask = (1 << i); + for (int j = 0; j < n; j++) { + if ((nums[j] & mask) > 0) { + x++; + } + if ((j & mask) > 0) { + y++; + } + } + if (x > y) { + res |= mask; + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0297.java b/leetcode_Java/Solution0297.java new file mode 100644 index 0000000..2cac3a7 --- /dev/null +++ b/leetcode_Java/Solution0297.java @@ -0,0 +1,121 @@ +// 297. 二叉树的序列化与反序列化 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + +// Your Codec object will be instantiated and called as such: +// Codec ser = new Codec(); +// Codec deser = new Codec(); +// TreeNode ans = deser.deserialize(ser.serialize(root)); + + +/* +递归: +1、序列化: + 1)方法功能:入参是一个节点,返回节点的序列化结果 + 2)终止条件:节点为空时,返回 "X," + 3)一个节点处理过程和返回结果:节点不为空,返回 "节点值," + 4)递归调用:左右节点同样需要序列化,因此调用同样的方法递归处理,获取结果 + 5)递归顺序:后序遍历,要构造“根左右”的序列化结果,需要先处理左右节点,再处理根节点 + 6)使用递归调用结果和返回结果:获取左右节点的序列化结果,构造返回 "根节点值,左节点值,右节点值," +2、反序列化:序列化字符串先根据逗号分隔数组,再解析成队列 + 1)方法功能:入参是一个队列,弹出队头字符串,解析成数字后,构造根节点,返回该节点 + 2)终止条件:字符串为"X",返回空 + 3)一个节点处理过程和返回结果:队头字符串,解析成数字后,构造根节点,返回该节点 + 4)递归调用:左右节点同样需要构造,因此调用同样的方法递归处理,获取结果 + 5)递归顺序:前序遍历,要先构造根节点,再构造左右节点 + 6)使用递归调用结果和返回结果:获取左右节点后,将其与根节点连接,返回根节点 + */ +public class Codec { + public String serialize(TreeNode root) { + if (root == null) { + return "X,"; + } + String leftSerialize = serialize(root.left); + String rightSerialize = serialize(root.right); + return root.val + "," + leftSerialize + rightSerialize; + } + + public TreeNode deserialize(String data) { + String[] splits = data.split(","); + Deque queue = new ArrayDeque<>(Arrays.asList(splits)); + return build(queue); + } + + private TreeNode build(Deque queue) { + String s = queue.poll(); + if (s.equals("X")) { + return null; + } + TreeNode node = new TreeNode(Integer.parseInt(s)); + node.left = build(queue); + node.right = build(queue); + return node; + } +} + + +/* +广度优先搜索: +1、序列化:层序遍历,用队列存放节点,遍历当前层的同时添加下一层节点,每层节点从左到右转化成字符串,空节点为 "X,",非空节点为 "节点值," +2、反序列化: + 1)序列化字符串先根据逗号分隔数组,获取数组首元素构造根节点,将根节点加入队列。 + 2)从队列弹出节点后,再从序列化数组获取该节点的左右节点字符串,构造左右节点,并将左右节点加入队列。循环读取队列,直到全部构造完成 + 3)返回根节点 + */ +public class Codec { + public String serialize(TreeNode root) { + if (root == null) { + return "X,"; + } + StringBuilder sb = new StringBuilder(); + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + if (node != null) { + sb.append(node.val + ","); + queue.add(node.left); + queue.add(node.right); + } else { + sb.append("X,"); + } + } + return sb.toString(); + } + + public TreeNode deserialize(String data) { + if (data.equals("X,")) { + return null; + } + String[] splits = data.split(","); + Queue queue = new LinkedList<>(); + TreeNode root = new TreeNode(Integer.parseInt(splits[0])); + queue.add(root); + int i = 1; + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + if (!"X".equals(splits[i])) { + TreeNode left = new TreeNode(Integer.parseInt(splits[i])); + node.left = left; + queue.add(left); + } + i++; + if (!"X".equals(splits[i])) { + TreeNode right = new TreeNode(Integer.parseInt(splits[i])); + node.right = right; + queue.add(right); + } + i++; + } + return root; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0300.java b/leetcode_Java/Solution0300.java new file mode 100644 index 0000000..dc6d68b --- /dev/null +++ b/leetcode_Java/Solution0300.java @@ -0,0 +1,35 @@ +// 300. 最长递增子序列 + + +/* +动态规划: +1、题目简化:求数组的最长递增子序列的长度 +2、定义dp数组:dp[i] 表示以索引i的元素结尾的最长递增子序列的长度 +3、初始化: + 1)一维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)dp[i] = 1 表示每一个位置i的递增子序列的长度至少是1 +4、状态转移方程:if (nums[i] > nums[j]) dp[i] = Math.max(dp[i], dp[j] + 1); + 位置i的最长递增子序列长度 等于j从0到i-1各个位置的 最长递增子序列长度加1的 最大值 +5、遍历dp数组填表:第一个for循环遍历dp数组的未知位置,第二个for循环遍历dp数组的已知位置,根据状态转移方程获取已知结果计算未知结果 +6、返回结果:遍历时比较每个位置结尾时的最长递增子序列的长度,并记录最大值,最后返回最大值 + */ +public class Solution { + public int lengthOfLIS(int[] nums) { + int n = nums.length; + if (n < 2) { + return n; + } + int[] dp = new int[n]; + Arrays.fill(dp, 1); + int res = 1; + for (int i = 1; i < n; i++) { + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + res = Math.max(res, dp[i]); + } + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0301.java b/leetcode_Java/Solution0301.java new file mode 100644 index 0000000..f608f17 --- /dev/null +++ b/leetcode_Java/Solution0301.java @@ -0,0 +1,140 @@ +// 301. 删除无效的括号 + + +/* +回溯: +1、题目要求将所有最长合法方案输出,因此不可能有别的优化,只能进行「爆搜」,可以使用 DFS 实现回溯搜索 +2、所有的合法方案,必然有左括号的数量与右括号数量相等。令左括号的得分为 1;右括号的得分为 −1。则合法方案会有如下性质: + 1)对于一个合法的方案而言,必然有最终得分为 0; + 2)搜索过程中不会出现得分值为 负数 的情况,即右括号数量大于左括号数量时为非法 +3、预处理出「爆搜」过程的最大得分:maxScore = min(左括号的数量, 右括号的数量),即合法左括号先全部出现在左边,之后使用最多的合法右括号进行匹配 +4、枚举过程中出现字符分三种情况: + 1)左括号:如果增加当前 ( 后,仍为合法子串,即 score+1 <= maxscore 时,我们可以选择添加该左括号,也能选择不添加 + 2)右括号:如果增加当前 ) 后,仍为合法子串,即 score-1 >= 0 时,我们可以选择添加该右括号,也能选择不添加 + 3)普通字符:直接添加 +5、使用 Set 进行方案去重,maxLen 记录「爆搜」过程中的最大子串,然后只保留长度等于 maxLen 的子串 +6、回溯过程的公共变量作为成员变量,方法独有的变量作为局部变量 +7、定义递归函数: + 1)剪枝条件:分数score非法,即左括号或右括号的数量多了 + 2)终止条件:遍历完字符串,判断 分数是否为0、子串长度是否大于等于当前最大长度,若大于最大长度则更新最大长度,并清空集合,最后将将子串加入集合 + 3)递归回溯:遍历字符,调用递归方法构造并校验子串。由于变量的改变在入参处理,所以递归结束后 下一个递归参数仍然使用原变量处理,多个递归方法参数互不影响,即回溯 + 4)入参变化: + ① 一次递归即遍历下一个字符,索引index加1 + ② 添加左括号时,分数score加1,子串subs加上该字符。不添加时分数score不变,子串subs不变 + ③ 添加右括号时,分数score减1,子串subs加上该字符。不添加时分数score不变,子串subs不变 + ④ 字母必须添加,分数score不变,子串subs加上该字符 + */ +class Solution { + int n, maxScore, maxLen; + String s; + Set set = new HashSet<>(); + public List removeInvalidParentheses(String s) { + this.s = s; + n = s.length(); + int left = 0, right = 0; + for (char c : s.toCharArray()) { + if (c == '(') { + left++; + } else if (c == ')') { + right++; + } + } + maxScore = Math.min(left, right); + track(0, 0, ""); + return new ArrayList<>(set); + } + + private void track(int index, int score, String subs) { + if (score < 0 || score > maxScore) { + return; + } + if (index == n) { + if (score == 0 && subs.length() >= maxLen) { + if (subs.length() > maxLen) { + maxLen = subs.length(); + set.clear(); + } + set.add(subs); + } + return; + } + char c = s.charAt(index); + if (c == '(') { + track(index + 1, score + 1, subs + String.valueOf(c)); + track(index + 1, score, subs); + } else if (c == ')') { + track(index + 1, score - 1, subs + String.valueOf(c)); + track(index + 1, score, subs); + } else { + track(index + 1, score, subs + String.valueOf(c)); + } + } +} + + +/* +1、上一解法是在搜索过程中去更新最后的 maxLen,但实际上可以通过预处理,得到最后的「应该删除的左括号数量」和「应该删掉的右括号数量」,来直接得到最终的 maxLen,因此可以多增加一层剪枝 +2、遍历字符串时,对左括号数量和右括号数量进行匹配抵消,最终剩下的数量就是应该删除的括号数量,由字符串长度 减去 应该删除的括号数量 得到 最终子串长度 +3、定义递归函数: + 1)剪枝条件:分数score非法,即左括号或右括号的数量多了。应该删除括号数量非法,即删多了 + 2)校验合法条件:应该删除括号数量为0、子串长度等于最大长度,则将子串加入集合 + 3)终止条件:遍历完字符串,索引等于字符串长度 + 4)递归回溯:遍历字符,调用递归方法构造并校验子串。由于变量的改变在入参处理,所以递归结束后 下一个递归参数仍然使用原变量处理,多个递归方法参数互不影响,即回溯 + 5)入参变化: + ① 一次递归即遍历下一个字符,索引index加1 + ② 添加左括号时,分数score加1,子串subs加上该字符。不添加时分数score不变,子串subs不变 + ③ 添加右括号时,分数score减1,子串subs加上该字符。不添加时分数score不变,子串subs不变 + ④ 字母必须添加,分数score不变,子串subs加上该字符 + ⑤ 不添加左括号时,应该删除左括号数量leftDel减1。添加时则不变 + ⑥ 不添加右括号时,应该删除右括号数量rightDel减1。添加时则不变 + */ +class Solution { + int n, maxScore, maxLen; + String s; + Set set = new HashSet<>(); + public List removeInvalidParentheses(String s) { + this.s = s; + n = s.length(); + int left = 0, right = 0; + int leftDel = 0, rightDel = 0; + for (char c : s.toCharArray()) { + if (c == '(') { + left++; + leftDel++; + } else if (c == ')') { + right++; + if (leftDel != 0) { + leftDel--; + } else { + rightDel++; + } + } + } + maxScore = Math.min(left, right); + maxLen = n - leftDel - rightDel; + track(0, 0, leftDel, rightDel, ""); + return new ArrayList<>(set); + } + + private void track(int index, int score, int leftDel, int rightDel, String subs) { + if (leftDel < 0 || rightDel < 0 || score < 0 || score > maxScore) { + return; + } + if (leftDel == 0 && rightDel == 0 && subs.length() == maxLen) { + set.add(subs); + } + if (index == n) { + return; + } + char c = s.charAt(index); + if (c == '(') { + track(index + 1, score + 1, leftDel, rightDel, subs + String.valueOf(c)); + track(index + 1, score, leftDel - 1, rightDel, subs); + } else if (c == ')') { + track(index + 1, score - 1, leftDel, rightDel, subs + String.valueOf(c)); + track(index + 1, score, leftDel, rightDel - 1, subs); + } else { + track(index + 1, score, leftDel, rightDel, subs + String.valueOf(c)); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0303.java b/leetcode_Java/Solution0303.java new file mode 100644 index 0000000..e7fd908 --- /dev/null +++ b/leetcode_Java/Solution0303.java @@ -0,0 +1,48 @@ +// 303. 区域和检索 - 数组不可变 + + +/* +暴力破解:直接累加计算区间和,时间复杂度O(n) + */ +class NumArray { + private int[] nums; + + public NumArray(int[] nums) { + this.nums = nums; + } + + public int sumRange(int left, int right) { + int res = 0; + for (int i = left; i <= right; i++) { + res += nums[i]; + } + return res; + } +} + + +/* +前缀和: +1、使用数组存放前缀和,preSum[n] 表示nums数组索引区间 [0, n-1] 的和 +2、计算某个区间元素和,可以直接通过前缀和相减得到,时间复杂度O(1) + */ +class NumArray { + private int[] preSum; + + public NumArray(int[] nums) { + preSum = new int[nums.length + 1]; + for (int i = 0; i < nums.length; i++) { + preSum[i + 1] = preSum[i] + nums[i]; + } + } + + public int sumRange(int left, int right) { + return preSum[right + 1] - preSum[left]; + } +} + +/** + * Your NumArray object will be instantiated and called as such: + * NumArray obj = new NumArray(nums); + * int param_1 = obj.sumRange(left,right); + */ \ No newline at end of file diff --git a/leetcode_Java/Solution0304.java b/leetcode_Java/Solution0304.java new file mode 100644 index 0000000..00159b9 --- /dev/null +++ b/leetcode_Java/Solution0304.java @@ -0,0 +1,64 @@ +// 304. 二维区域和检索 - 矩阵不可变 + + +/* +一维前缀和: +1、初始化时对矩阵的每一行计算前缀和,检索时对二维区域中的每一行计算子数组和,然后对每一行的子数组和计算总和。 +2、preSum[n][m] 表示矩阵matrix 左上角为(n, 0) 右下角为 (n, m-1) 的子矩形范围元素和 +3、preSum 初始化时比 matrix 多了一列,用于初始化前缀和矩阵首列为0 +4、检索的时间复杂度是 O(m) + */ +class NumMatrix { + private int[][] preSum; + + public NumMatrix(int[][] matrix) { + int n = matrix.length, m = matrix[0].length; + preSum = new int[n][m + 1]; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + preSum[row][col + 1] = preSum[row][col] + matrix[row][col]; + } + } + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + int res = 0; + for (int i = row1; i <= row2; i++) { + res += preSum[i][col2 + 1] - preSum[i][col1]; + } + return res; + } +} + + + +/* +二维前缀和: +1、preSum[n][m] 表示矩阵matrix 左上角为(0, 0) 右下角为 (n-1, m-1) 的子矩形范围元素和 +2、preSum 初始化时比 matrix 多了一行一列,用于初始化前缀和矩阵首行首列为0 +3、前缀和矩阵元素填充、计算子矩形元素和,都是通过其他子矩形的面积加减得到 +4、检索的时间复杂度是 O(1) + */ +class NumMatrix { + private int[][] preSum; + + public NumMatrix(int[][] matrix) { + int n = matrix.length, m = matrix[0].length; + preSum = new int[n + 1][m + 1]; + for (int row = 1; row <= n; row++) { + for (int col = 1; col <= m; col++) { + preSum[row][col] = preSum[row - 1][col] + preSum[row][col - 1] - preSum[row - 1][col -1] + matrix[row - 1][col - 1]; + } + } + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + return preSum[row2 + 1][col2 + 1] - preSum[row2 + 1][col1] - preSum[row1][col2 + 1] + preSum[row1][col1]; + } +} + +/** + * Your NumMatrix object will be instantiated and called as such: + * NumMatrix obj = new NumMatrix(matrix); + * int param_1 = obj.sumRegion(row1,col1,row2,col2); + */ \ No newline at end of file diff --git a/leetcode_Java/Solution0309.java b/leetcode_Java/Solution0309.java new file mode 100644 index 0000000..bed5d8c --- /dev/null +++ b/leetcode_Java/Solution0309.java @@ -0,0 +1,58 @@ +// 309. 最佳买卖股票时机含冷冻期 + + +/* +动态规划: +1、定义dp数组 + dp[i][0] 表示第i天交易结束后,持有股票,获取的最大利润 + dp[i][1] 表示第i天交易结束后,不持有股票,处于冷冻期,获取的最大利润(第i天卖出股票后就处于冷冻期,则第i+1天不能买入股票) + dp[i][2] 表示第i天交易结束后,不持有股票,不处于冷冻期,获取的最大利润 +2、初始化 + dp[0][0] = -prices[0] 表示第0天交易结束后,持有股票,获取的最大利润为-prices[0] + dp[0][1] = dp[0][2] = 0 表示第0天交易结束后,不持有股票,获取的最大利润为0。创建数组时默认为0,可省略 +3、状态转移方程 + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2] - prices[i]); // 今天持有股票。则前一天持有股票;或者前一天不持有股票、非冷冻期,且今天买入股票 + dp[i][1] = dp[i - 1][0] + prices[i]; // 今天不持有股票,处于冷冻期。则前一天持有股票,且今天卖出股票 + dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2]); // 今天不持有股票,不处于冷冻期。则前一天不持有股票,处于冷冻期;或者前一天不持有股票,不处于冷冻期 +4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:第i天交易结束后,不持有股票的两个状态比较获取的最大利润 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[][] dp = new int[n][3]; + dp[0][0] = -prices[0]; + dp[0][1] = dp[0][2] = 0; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2] - prices[i]); + dp[i][1] = dp[i - 1][0] + prices[i]; + dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2]); + } + return Math.max(dp[n - 1][1], dp[n - 1][2]); + } +} + + +/* +动态规划:状态压缩,使用变量存储状态 +1、状态压缩:每一天的状态只与前一天的状态有关,使用变量存储状态 dp[i][0]、dp[i][1]、dp[i][2] +2、定义状态: + dp0 表示第i天交易结束后,持有股票,获取的最大利润 + dp1 表示第i天交易结束后,不持有股票,处于冷冻期,获取的最大利润 + dp2 表示第i天交易结束后,不持有股票,不处于冷冻期,获取的最大利润 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int dp0 = -prices[0], dp1 = 0, dp2 = 0; + for (int i = 1; i < n; i++) { + int newDp0 = Math.max(dp0, dp2 - prices[i]); + int newDp1 = dp0 + prices[i]; + int newDp2 = Math.max(dp1, dp2); + dp0 = newDp0; + dp1 = newDp1; + dp2 = newDp2; + } + return Math.max(dp1, dp2); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0312.java b/leetcode_Java/Solution0312.java new file mode 100644 index 0000000..d662a32 --- /dev/null +++ b/leetcode_Java/Solution0312.java @@ -0,0 +1,68 @@ +// 312. 戳气球 + + +/* +动态规划: +1、题目简化:求戳破所有气球能获得硬币的最大数量 +2、定义dp数组: + 1)dp[start][end] 表示在开区间 (start,end) 能得到的最大硬币数 + 2)“开区间” 的意思是只能戳爆 start 和 end 之间的气球,start 和 end 不能戳 + 3)先别管前面是怎么戳的,只要管这个区间最后一个被戳破的是哪个气球,用 k 表示这个区间最后一个被戳爆的气球的索引 +3、初始化 + 1)气球数组的边界是数字1的气球,所以直接数组扩容首尾两个元素为1 + 2)dp数组不用初始化,默认为0,表示获得硬币的最大数量为0 +4、状态转移方程 + 1)因为 k 是最后一个被戳爆的气球,所以它两边没有气球了,只有这个开区间首尾的 start 和 end 了,这就是为什么DP的状态转移方程是只和 start 和 end 位置的数字有关 + 2)因为 k 是最后一个被戳爆的气球,所以左右两边的气球已经被戳爆了,且左右两边互不干扰,所以计算区间能得到的硬币数就需要把左右两边能得到的硬币数加上 + 戳爆k后开区间(start,end)能得到的硬币数 = 开区间(start,k)能得到的最大硬币数 + 戳爆k的得到的硬币数 + 开区间(k,end)能得到的最大硬币数 + 即 total = dp[start][k] + temp[start] * temp[k] * temp[end] + dp[k][end] + 3)由于区间 (start,end) 内每个气球都可以作为最后一个被戳爆的气球,所以把每个当成最后一个被戳爆的气球计算区间能得到的硬币数,最后取最大值就得到了在开区间 (start,end) 能得到的最大硬币数 +5、遍历dp数组填表 + 第一个for循环遍历区间长度,从最小的长度3开始 + 第二个for循环遍历区间的起始端点 + 第三个for循环遍历区间内最后一个被戳爆的气球 +6、返回结果:包含整个气球数组范围的状态就是结果 + +nums = [3,8,5] +temp = [1,3,8,5,1] + +由小问题推到大问题: + 1 3 8 5 1 + ↑_____↑ +start end +====================== + 1 3 8 5 1 + ↑_____↑ +====================== + 1 3 8 5 1 + ↑_____↑ +====================== + 1 3 8 5 1 + ↑________↑ +====================== + 1 3 8 5 1 + ↑________↑ +====================== + 1 3 8 5 1 + ↑___________↑ + */ +class Solution { + public int maxCoins(int[] nums) { + int n = nums.length; + int[] temp = new int[n + 2]; + System.arraycopy(nums, 0, temp, 1, n); + temp[0] = temp[n + 1] = 1; + int[][] dp = new int[n + 2][n + 2]; + for (int len = 3; len <= n + 2; len++) { + for (int start = 0; start <= n + 2 - len; start++) { + int res = 0; + int end = start + len - 1; + for (int k = start + 1; k < end; k++) { + res = Math.max(res, dp[start][k] + temp[start] * temp[k] * temp[end] + dp[k][end]); + } + dp[start][end] = res; + } + } + return dp[0][n + 1]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0316.java b/leetcode_Java/Solution0316.java new file mode 100644 index 0000000..585b3f8 --- /dev/null +++ b/leetcode_Java/Solution0316.java @@ -0,0 +1,45 @@ +// 316. 去除重复字母 + + +/* +单调递增栈 +实现思路: +1、利用单调递增栈,如果当前字符小于栈顶字符,则栈顶字符出栈,最后当前字符入栈,保证了栈内单调递增,删除了高位上较大的字符,使字典序更小 +2、用inStack数组记录字符是否在栈中,存在则跳过,保证字母不重复 +3、用count数组记录字符的个数,弹出时校验剩余个数,保证字母用一次,使字典序更小 + +算法过程: +1、遍历字符数组 + 1)每遍历一个字符,该字符的剩余个数就减1 + 2)如果字符已经在栈中,那么不能重复添加,需跳过 + 3)栈不为空 且 当前字符小于栈顶字符 且 栈顶字符剩余个数大于0,那么弹出栈顶字符且记录不在栈中。 + 判断 栈顶字符剩余个数大于0 是因为当前在高位弹出该字符能使字典序更小,但要满足每个字符出现一次,所以有剩余后面再加入,当前才可以弹出 + 4)将当前字符入栈,并记录在栈中 +2、栈不为空时,从栈底弹出字符拼凑字符串,返回字符串 + */ +class Solution { + public String removeDuplicateLetters(String s) { + int[] count = new int[256]; + boolean[] inStack = new boolean[256]; + Deque stack = new ArrayDeque<>(); + for (char c : s.toCharArray()) { + count[c]++; + } + for (char c : s.toCharArray()) { + count[c]--; + if (inStack[c]) { + continue; + } + while (!stack.isEmpty() && c < stack.peek() && count[stack.peek()] > 0) { + inStack[stack.pop()] = false; + } + stack.push(c); + inStack[c] = true; + } + StringBuilder res = new StringBuilder(); + while (!stack.isEmpty()) { + res.append(stack.pollLast()); + } + return res.toString(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0322.java b/leetcode_Java/Solution0322.java new file mode 100644 index 0000000..f84eb65 --- /dev/null +++ b/leetcode_Java/Solution0322.java @@ -0,0 +1,141 @@ +// 322. 零钱兑换 + + +/* +递归 + 备忘录 +1、dfs(n)定义:输入目标金额n,返回凑出目标金额n的最少硬币数量 +2、备忘录数组memo[n]表示凑出金额n的最少硬币数量,凑不出时最小值为-1,故初始化为-2 +3、定义递归函数 + 1)终止条件:目标金额为0返回0,目标金额为负数返回-1,目标金额在备忘录中有值则直接返回该值 + 2)遍历硬币数组,调用递归函数,比较得到取不同面额的硬币时最少的硬币数量,记录结果并返回结果 + */ +class Solution { + public int coinChange(int[] coins, int amount) { + int[] memo = new int[amount + 1]; + Arrays.fill(memo, -2); + return dfs(memo, coins, amount); + } + + private int dfs(int[] memo, int[] coins, int amount) { + if (amount == 0) { + return 0; + } + if (amount < 0) { + return -1; + } + if (memo[amount] != -2) { + return memo[amount]; + } + int res = Integer.MAX_VALUE; + for (int coin : coins) { + int subRes = dfs(memo, coins, amount - coin); + if (subRes == -1) { + continue; + } + res = Math.min(res, subRes + 1); + } + memo[amount] = (res == Integer.MAX_VALUE) ? -1 : res; + return memo[amount]; + } +} + + +/* +动态规划:完全背包,二维数组 +1、题目:给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。你可以认为每种硬币的数量是无限的。 +2、题目简化:求凑成总金额amount所需的最少硬币数 +3、定义dp数组:dp[i][j] 表示使用前i个硬币,凑成总金额j所需的最少硬币数 +4、初始化: + 1)二维dp数组扩容:增加0个硬币、总金额0这一最小规模的情况,方便初始化 + 2)首列 dp[i][0] 表示使用前i个硬币,凑成总金额0所需的最少硬币数为0 + 3)其他填充一个不可能的硬币数,使得不影响计算,也方便状态转移时取最小值 +5、状态转移方程 + if (j - coins[i - 1] >= 0) dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - coins[i - 1]] + 1); // 金额足够,“不用”和“用”两种情况比较出最少 + else dp[i][j] = dp[i - 1][j]; // 金额不够,只能选择“不用”该硬币 + 注意:dp[i - 1][j - coins[i - 1]] 表示第i个硬币只用一次,属于0-1背包。dp[i][j - coins[i - 1]] 表示第i个硬币重复使用,属于完全背包。 +6、遍历dp数组填表:第一层遍历硬币,第二层遍历金额,都从1开始,正序遍历。两个for循环先后都可以,因为计算当前状态只需要当前行左边的状态和上一行的状态 +7、返回结果:最后一个状态就是结果 + +二维dp更新过程,从左到右,从上到下 +coins = [1, 2, 5], amount = 11 + 0 1 2 3 4 5 6 7 8 9 10 11 +x 0 12 12 12 12 12 12 12 12 12 12 12 +1 0 1 2 3 4 5 6 7 8 9 10 11 +2 0 1 1 2 2 3 3 4 4 5 5 6 +5 0 1 1 2 2 1 2 2 3 3 2 3 + */ +class Solution { + public int coinChange(int[] coins, int amount) { + int n = coins.length; + int[][] dp = new int[n + 1][amount + 1]; + for (int i = 0; i <= n; i++) { + for (int j = 1; j <= amount; j++) { + dp[i][j] = amount + 1; + } + } + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= amount; j++) { + if (j - coins[i - 1] >= 0) { + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - coins[i - 1]] + 1); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return (dp[n][amount] == amount + 1) ? -1 : dp[n][amount]; + } +} + + +/* +动态规划:完全背包,一维数组 +1、定义dp数组:dp[i] 表示凑成总金额i所需的最少硬币数 +2、状态转移方程:dp[i] = Math.min(dp[i], dp[i-coin]+1); 需要比较多种硬币情况下的最小值 +3、初始化: + dp[i]=amount+1; 填充一个不可能的硬币数,使得不影响计算,也方便状态转移时取最小值 + dp[0]=0; 表示凑成总金额0所需的最少硬币数为0,方便后面推导 +4、遍历dp数组填表: + 1)第一个for循环遍历dp数组的未知位置,第二个for循环遍历硬币数组,根据条件获取dp数组的已知位置,根据状态转移方程取已知结果汇总计算未知结果 + 2)先物品再背包是计算组合,先背包再物品是计算排列,本题物品背包顺序无关,必须正序遍历背包才能重复使用物品 +5、返回结果:最后一个状态就是结果 + +一维dp更新过程,从左到右 +coins = [1, 2, 5], amount = 11 +0 12 12 12 12 12 12 12 12 12 12 12 + 1 2 3 4 5 6 7 8 9 10 11 + 1 2 2 3 3 4 4 5 5 6 + 1 2 2 3 3 2 3 + */ +class Solution { + public int coinChange(int[] coins, int amount) { + int[] dp = new int[amount + 1]; + Arrays.fill(dp, amount + 1); + dp[0] = 0; + for (int coin : coins) { + for (int i = coin; i <= amount; i++) { + dp[i] = Math.min(dp[i], dp[i - coin] + 1); + } + } + return (dp[amount] == amount + 1) ? -1 : dp[amount]; + } +} + + +/* +其他同上。遍历dp数组填表:第一个for循环遍历硬币数组,第二个for循环遍历dp数组的未知位置,根据条件获取dp数组的已知位置,根据状态转移方程取已知结果汇总计算未知结果 + */ +class Solution { + public int coinChange(int[] coins, int amount) { + int[] dp = new int[amount + 1]; + Arrays.fill(dp, amount + 1); + dp[0] = 0; + for (int i = 1; i <= amount; i++) { + for (int coin : coins) { + if (i - coin >= 0) { + dp[i] = Math.min(dp[i], 1 + dp[i - coin]); + } + } + } + return (dp[amount] == amount + 1) ? -1 : dp[amount]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0337.java b/leetcode_Java/Solution0337.java new file mode 100644 index 0000000..4f88384 --- /dev/null +++ b/leetcode_Java/Solution0337.java @@ -0,0 +1,119 @@ +// 337. 打家劫舍 III + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +通过三个方法不断递进解决问题 +解法一通过递归实现,虽然解决了问题,但是复杂度太高,结果超时 +解法二通过记忆化存储,解决方法一中的重复子问题,实现了性能的提升,但还是存在重复递归调用 +解法三直接省去了重复子问题,递归到底部,再自底向上返回,复杂度O(n),性能又提升了一步 + */ + + +/* +定义递归函数: +1、方法功能:入参是一个节点,返回在该节点时能偷窃到的最高金额 +2、终止条件:节点为空时返回0 +3、返回结果:节点不为空时返回节点值 +4、递归逻辑: + 1)爷爷作为根节点, + 爷爷偷时,两个儿子不能偷,四个孙子能偷 ==> 最高金额 = 爷爷偷钱 + 四个孙子偷钱 + 爷爷不偷时,两个儿子能偷,四个孙子不能偷 ==> 最高金额 = 两个儿子偷钱 + 2)根节点偷窃最高金额 = max(爷爷偷钱 + 四个孙子偷钱, 两个儿子偷钱) + 3)由于儿子、孙子都要计算偷窃最高金额,所以调用同样的方法获取结果,再拿结果进行比较处理,最终返回根节点的最高金额 +5、问题:爷爷计算时会同时计算儿子和孙子,当儿子变成爷爷后,又会再计算一遍爷爷、儿子、孙子,存在重复计算 + */ +class Solution { + public int rob(TreeNode root) { + if (root == null) { + return 0; + } + int money = root.val; + if (root.left != null) { + money += rob(root.left.left) + rob(root.left.right); + } + if (root.right != null) { + money += rob(root.right.left) + rob(root.right.right); + } + return Math.max(money, rob(root.left) + rob(root.right)); + } +} + + +/* +增加记忆存储,避免重复子问题的重复计算,但仍然存在重复调用获取爷爷、儿子、孙子的最高金额,存在性能损耗 + */ +class Solution { + HashMap memo = new HashMap<>(); + + public int rob(TreeNode root) { + if (root == null) { + return 0; + } + if (memo.containsKey(root)) { + return memo.get(root); + } + int money = root.val; + if (root.left != null) { + money += rob(root.left.left) + rob(root.left.right); + } + if (root.right != null) { + money += rob(root.right.left) + rob(root.right.right); + } + int maxMoney = Math.max(money, rob(root.left) + rob(root.right)); + memo.put(root, maxMoney); + return maxMoney; + } +} + + +/* +1、换一种办法来定义此问题,每个节点可选择偷或者不偷两种状态,相连节点不能一起偷 + 1)当前节点选择偷时,那么两个孩子节点就不能选择偷了 + 2)当前节点选择不偷时,两个孩子节点只需要拿最多的钱出来就行 +2、使用一个大小为 2 的数组记录节点偷不偷时的最高金额 int[] money = new int[2]; 0代表不偷,1代表偷 +3、任何一个节点能偷到的最高金额的状态可以定义为 + 1)当前节点选择不偷:当前节点能偷到的最高金额 = 左孩子偷或不偷的最高金额 + 右孩子偷或不偷的最高金额 + 2)当前节点选择偷:当前节点能偷到的最高金额 = 左孩子不偷的最高金额 + 右孩子不偷的最高金额 + 当前节点的金额 +4、定义递归函数: + 1)方法功能:入参是一个节点,返回该节点偷不偷时的最高金额数组 + 2)终止条件:节点为空时,返回空数组 + 3)返回结果:节点不为空时,将偷和不偷的金额存入数组,返回该数组 + 4)递归逻辑:由于左右孩子都要计算偷不偷时的最高金额数组,因此调用同样的方法获取结果后,再拿结果进行比较处理,最终返回根节点的最高金额数组 +5、调用递归函数得到根节点偷不偷时的最高金额数组,再从两者取最大,然后返回结果 +6、此解法自顶向下递归,然后自底向上返回结果,只进行一次,没有重复调用,性能提升 + */ +class Solution { + public int rob(TreeNode root) { + int[] money = robHelper(root); + return Math.max(money[0], money[1]); + } + + private int[] robHelper(TreeNode root) { + if (root == null) { + return new int[2]; + } + int[] money = new int[2]; + int[] leftMoney = robHelper(root.left); + int[] rightMoney = robHelper(root.right); + money[0] = Math.max(leftMoney[0], leftMoney[1]) + Math.max(rightMoney[0], rightMoney[1]); + money[1] = root.val + leftMoney[0] + rightMoney[0]; + return money; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0338.java b/leetcode_Java/Solution0338.java new file mode 100644 index 0000000..ec99d69 --- /dev/null +++ b/leetcode_Java/Solution0338.java @@ -0,0 +1,59 @@ +// 338. 比特位计数 + + +/* +动态规划: +i为偶数时,f(i)=f(i/2),因为i/2本质上是i的二进制左移一位,低位补零,所以1的数量不变 +i为奇数时,f(i)=f(i-1)+1,因为i-1为偶数,而偶数的二进制最低位一定是0,偶数加1后最低位变为1且不会进位 + */ +class Solution { + public int[] countBits(int n) { + int[] dp = new int[n + 1]; + for (int i = 1; i <= n; i++) { + if (i % 2 == 0) { + dp[i] = dp[i / 2]; + } else { + dp[i] = dp[i / 2] + 1; + } + } + return dp; + } +} + + +/* +逻辑同上,“与”写法。i&1结果偶数为0,奇数为1 + */ +class Solution { + public int[] countBits(int n) { + int[] dp = new int[n + 1]; + for (int i = 1; i <= n; i++) { + dp[i] = dp[i / 2] + (i & 1); + } + return dp; + } +} + + +/* +1、直接计算每个数的二进制中1的个数 +2、n &= n - 1,该运算将 n 的二进制表示的最后一个 1 变成 0,操作几次说明有几个1 + */ +class Solution { + public int[] countBits(int n) { + int[] res = new int[n + 1]; + for (int i = 0; i <= n; i++) { + res[i] = countOne(i); + } + return res; + } + + private int countOne(int n) { + int count = 0; + while (n > 0) { + n &= n - 1; + count++; + } + return count; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0347.java b/leetcode_Java/Solution0347.java new file mode 100644 index 0000000..14934ac --- /dev/null +++ b/leetcode_Java/Solution0347.java @@ -0,0 +1,182 @@ +// 347. 前 K 个高频元素 +// 主要思路同“215. 数组中的第K个最大元素” + +/* +优先级队列,最小堆: +1、统计元素的出现频率保存在map中 +2、优先级队列按照元素的频率 对元素升序排序,即小元素在队头,队列只保存最多k个元素 +3、遍历map,如果队列小于k,则直接将元素存入队列。否则跟队头元素比较频率,队头元素频率低则出栈,新元素入栈 +4、最终队列保存了前K个高频元素,转化成数组返回 + */ +class Solution { + public int[] topKFrequent(int[] nums, int k) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + PriorityQueue queue = new PriorityQueue<>((a, b) -> map.get(a) - map.get(b)); + for(Integer num : map.keySet()) { + if (queue.size() < k) { + queue.add(num); + } else if (map.get(num) > map.get(queue.peek())) { + queue.remove(); + queue.add(num); + } + } + int n = queue.size(); + int[] res = new int[n]; + for(int i = 0; i < n; i++) { + res[i] = queue.poll(); + } + return res; + } +} + + +/* +快速排序 +1、统计元素的出现频率保存在numToCountMap中,即 {元素:频率} +2、将频率对应的元素保存在countToNumMap中,即 {频率:[元素1,元素2]} +3、将频率保存在频率数组countArray中,对数组进行快速排序,得到频率第k大的索引 +4、遍历topk频率,找到对应的元素,加入结果数组中。要保证同一频率的元素优先取尽,且只取k个,结果数组不越界 + +与“215. 数组中的第K个最大元素”区别: +1、本题需要对数组元素、频率处理。215题不需要 +2、本题排序方法返回的是第k大的元素的索引,再通过索引取前k个高频元素。215题排序方法直接返回第K个最大元素 + */ +class Solution { + public int[] topKFrequent(int[] nums, int k) { + Map numToCountMap = new HashMap<>(); + for (int num : nums) { + numToCountMap.put(num, numToCountMap.getOrDefault(num, 0) + 1); + } + + Map> countToNumMap = new HashMap<>(); + int n = numToCountMap.size(); + int index = 0; + int[] countArray = new int[n]; + for (int num : numToCountMap.keySet()) { + int count = numToCountMap.get(num); + ArrayList list = countToNumMap.getOrDefault(count, new ArrayList()); + list.add(num); + countToNumMap.put(count, list); + countArray[index++] = count; + } + + int topkIndex = mainSort(countArray, 0, n - 1, n - k); + int[] res = new int[k]; + index = 0; + for (int i = topkIndex; i < n; i++) { + ArrayList list = countToNumMap.get(countArray[i]); + while (list.size() > 0 && index < k) { + res[index++] = list.get(0); + list.remove(0); + } + } + return res; + } + + private int mainSort(int[] nums, int left, int right, int target) { + if (left == right) { + return left; + } + int res; + int mid = partition(nums, left, right); + if (mid == target) { + res = mid; + } else if (mid > target) { + res = mainSort(nums, left, mid - 1, target); + } else { + res = mainSort(nums, mid + 1, right, target); + } + return res; + } + + private int partition(int[] nums, int left, int right) { + int index = left + 1; + for (int i = index; i <= right; i++) { + if (nums[i] < nums[left]) { + swap(nums, i, index); + index++; + } + } + swap(nums, left, index - 1); + return index - 1; + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} + + +/* +最大堆排序:思路同上,排序方法不同 + */ +class Solution { + public int[] topKFrequent(int[] nums, int k) { + Map numToCountMap = new HashMap<>(); + for (int num : nums) { + numToCountMap.put(num, numToCountMap.getOrDefault(num, 0) + 1); + } + + Map> countToNumMap = new HashMap<>(); + int n = numToCountMap.size(); + int index = 0; + int[] countArray = new int[n]; + for (int num : numToCountMap.keySet()) { + int count = numToCountMap.get(num); + ArrayList list = countToNumMap.getOrDefault(count, new ArrayList()); + list.add(num); + countToNumMap.put(count, list); + countArray[index++] = count; + } + + int topkIndex = mainSort(countArray, k); + int[] res = new int[k]; + index = 0; + for (int i = topkIndex; i < n; i++) { + ArrayList list = countToNumMap.get(countArray[i]); + while (list.size() > 0 && index < k) { + res[index++] = list.get(0); + list.remove(0); + } + } + return res; + } + + public int mainSort(int[] nums, int k) { + int n = nums.length; + for (int i = n / 2 - 1; i >= 0; i--) { + maxHeapify(nums, i, n); + } + while (n > 0 && k > 0) { + swap(nums, 0, n - 1); + n--; + k--; + maxHeapify(nums, 0, n); + } + return n; + } + + private void maxHeapify(int[] nums, int root, int n) { + int maxIndex = root; + int left = root * 2 + 1, right = root * 2 + 2; + if (left < n && nums[left] > nums[maxIndex]) + maxIndex = left; + if (right < n && nums[right] > nums[maxIndex]) + maxIndex = right; + if (maxIndex != root) { + swap(nums, maxIndex, root); + maxHeapify(nums, maxIndex, n); + } + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0392.java b/leetcode_Java/Solution0392.java new file mode 100644 index 0000000..b87d5eb --- /dev/null +++ b/leetcode_Java/Solution0392.java @@ -0,0 +1,41 @@ +// 392. 判断子序列 + + +/* +求字符串t是否为字符串s的子序列,实际就是“1143.最长公共子序列”,得到最长长度再判断是否等于t的长度 + */ +class Solution { + public boolean isSubsequence(String s, String t) { + int n = s.length(), m = t.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (s.charAt(i - 1) == t.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[n][m] == n ? true : false; + } +} + + +/* +双指针:两个指针分别指向字符串s和t,当两个指针指向的字符相等时 i指针才向右移动一步,j指针每次都向右移动一步,只要其中一个字符串遍历完就结束, + 最后判断i指针是否到了末尾,是则表示s是t的子序列,否则不是 + */ +class Solution { + public boolean isSubsequence(String s, String t) { + int n = s.length(), m = t.length(); + int i = 0, j = 0; + while (i < n && j < m) { + if (s.charAt(i) == t.charAt(j)) { + i++; + } + j++; + } + return i == n ? true : false; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0394.java b/leetcode_Java/Solution0394.java new file mode 100644 index 0000000..eea3683 --- /dev/null +++ b/leetcode_Java/Solution0394.java @@ -0,0 +1,126 @@ +// 394. 字符串解码 + + +/* +栈:(这种解法更容易理解) +1、把所有字符入栈,除了']' +2、从栈取出[]内的字符串 +3、弹出'[',丢弃 +4、从栈获取倍数数字 +5、根据倍数把字母入栈 +6、把栈里面所有的字母取出来,得到结果 + */ +class Solution { + public String decodeString(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (c != ']') { + stack.push(c); + } else { + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty() && Character.isLetter(stack.peek())) { + sb.insert(0, stack.pop()); + } + String sub = sb.toString(); + stack.pop(); + sb = new StringBuilder(); + while (!stack.isEmpty() && Character.isDigit(stack.peek())) { + sb.insert(0, stack.pop()); + } + int count = Integer.valueOf(sb.toString()); + while (count > 0) { + for (char ch : sub.toCharArray()) { + stack.push(ch); + } + count--; + } + } + } + StringBuilder res = new StringBuilder(); + while (!stack.isEmpty()) { + res.insert(0, stack.pop()); + } + return res.toString(); + } +} + + +/* +栈: +1、外层的解码需要等待内层解码的结果。先扫描的字符还用不上,但不能忘了它们。我们准备由内到外,层层解决[],需要保持对字符的记忆,于是用栈。 +2、变量含义: + kStack:存放每一层[]的倍数,遇到'['时入栈暂存,遇到']'时出栈计算当前层解码结果 + resStack:存放上一层[]的子串,遇到'['时入栈暂存,遇到']'时出栈与当前层解码结果拼接 + res:表示当前层[]的子串,最外层没有[] + k:表示当前层[]的倍数 + temp:表示当前层[]的解码结果 +2、入栈时机:遇到'[',意味着要开始解决内层的字符了,外层的数字和子串入栈暂存,并且变量归零用于内层继续计算 + 1)当遇到'[',已经扫描的数字就是遇到的[]的“倍数”,入栈暂存 + 2)当遇到'[',已经扫描的子串也入栈暂存,括号里的字符解码完后,再一起参与构建字符串 +3、出栈时机:遇到']',内层的字符串扫描完了,数字出栈构建新子串,旧子串出栈与新子串拼接得到最新结果 + +========== 过程一 ========= +s = "abc3[a2[d]]ef" + ↑ +k = 3 +res = "abc" +stack = [(3, "abc")] +========== 过程二 ========= +s = "abc3[a2[d]]ef" + ↑ +k = 2 +res = "a" +stack = [(3, "abc"), (2, "a")] +========== 过程三 ========= +s = "abc3[a2[d]]ef" + ↑ +k = 0 +res = "d" +curk = 2 +oldres = "a" +stack = [(3, "abc")] +temp = curk * res = "dd" +res = oldres + curk * res = "add" +========== 过程四 ========= +s = "abc3[a2[d]]ef" + ↑ +k = 0 +res = "add" +curk = 3 +oldres = "abc" +stack = [(3, "abc")] +temp = curk * res = "addaddadd" +res = oldres + curk * res = "abcaddaddadd" +========== 过程五 ========= +s = "abc3[a2[d]]ef" + ↑ +res = "abcaddaddaddef" + */ +class Solution { + public String decodeString(String s) { + Deque kStack = new ArrayDeque<>(); + Deque resStack = new ArrayDeque<>(); + StringBuilder res = new StringBuilder(); + int k = 0; + for (char c : s.toCharArray()) { + if (c >= '0' && c <= '9') { + k = k * 10 + (c - '0'); + } else if (c == '[') { + kStack.push(k); + resStack.push(res); + k = 0; + res = new StringBuilder(); + } else if (c == ']') { + StringBuilder temp = new StringBuilder(); + int kCur = kStack.pop(); + for (int i = 0; i < kCur; i++) { + temp.append(res); + } + res = resStack.pop().append(temp); + } else { + res.append(c); + } + } + return res.toString(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0399.java b/leetcode_Java/Solution0399.java new file mode 100644 index 0000000..ef97bda --- /dev/null +++ b/leetcode_Java/Solution0399.java @@ -0,0 +1,89 @@ +// 399. 除法求值 + + +class Solution { + public double[] calcEquation(List> equations, double[] values, List> queries) { + int size = equations.size(); + Map map = new HashMap<>(2 * size); + UnionFind unionFind = new UnionFind(2 * size); + int id = 0; + double[] res = new double[queries.size()]; + for (List list : equations) { + String val1 = list.get(0); + String val2 = list.get(1); + if (!map.containsKey(val1)) { + map.put(val1, id); + id++; + } + if (!map.containsKey(val2)) { + map.put(val2, id); + id++; + } + } + for (int i = 0; i < size; i++) { + int val1 = map.get(equations.get(i).get(0)); + int val2 = map.get(equations.get(i).get(1)); + unionFind.union(val1, val2, values[i]); + } + for (int i = 0; i < queries.size(); i++) { + if (map.containsKey(queries.get(i).get(0)) && map.containsKey(queries.get(i).get(1))) { + int val1 = map.get(queries.get(i).get(0)); + int val2 = map.get(queries.get(i).get(1)); + res[i] = unionFind.getValue(val1, val2); + } else { + res[i] = -1.0d; + } + } + return res; + } +} + +class UnionFind { + int[] parent; + double[] weight; // 表示当前节点到根节点的值 + + public UnionFind(int size) { + this.parent = new int[size]; + this.weight = new double[size]; + for (int i = 0; i < size; i++) { + parent[i] = i; + weight[i] = 1.0d; + } + } + + //找到当前节点的根节点,在查询的同时进行路径压缩 + public int find(int x) { + if (x != parent[x]) { + int temp = parent[x]; + parent[x] = find(parent[x]); + weight[x] = weight[x] * weight[temp]; + } + return parent[x]; + } + + //将两个节点进行合并 + public void union(int x, int y, double value) { + int rootX = find(x); + int rootY = find(y); + if (rootX == rootY) { + return; + } else { + parent[rootX] = rootY; + weight[rootX] = value * weight[y] / weight[x]; + } + } + + //判断两个节点是否属于同一个分组 + public boolean isConnected(int x, int y) { + return find(x) == find(y); + } + + //返回连个节点的比值 + public double getValue(int x, int y) { + if (!isConnected(x, y)) { + return -1.0d; + } else { + return weight[x] / weight[y]; + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0402.java b/leetcode_Java/Solution0402.java new file mode 100644 index 0000000..51744c0 --- /dev/null +++ b/leetcode_Java/Solution0402.java @@ -0,0 +1,37 @@ +// 402. 移掉 K 位数字 + + +/* +单调递增栈: +1、最小的数字就是尽可能保证高位数字更小且升序,所以要删除高位较大的数字。 + 利用单调递增栈的特性,栈内元素升序,遇到比栈顶元素小的数时 栈顶元素出栈,小数入栈,这样在某一高位上就用小数替代了大数,使整体数字更小 +2、遍历数字 + 1)栈不为空 且 当前数字小于栈顶数字 且 仍可移除数字,弹出栈顶数字,循环处理直到不满足条件 + 2)栈不为空 或 数字不为0,则数字入栈,保证了栈底数字不为0 +3、遍历结束后如果没删够k个数字,那么继续从栈顶弹出元素,即删除低位数字 +4、从栈底弹出元素,拼凑字符串。如果字符串为空则返回"0",否则返回该字符串 + */ +class Solution { + public String removeKdigits(String num, int k) { + Deque stack = new ArrayDeque<>(); + for (char c : num.toCharArray()) { + while (!stack.isEmpty() && c < stack.peek() && k > 0) { + stack.pop(); + k--; + } + if (c != '0' || !stack.isEmpty()) { + stack.push(c); + } + } + StringBuffer res = new StringBuffer(); + while (!stack.isEmpty()) { + if (k > 0) { + stack.pop(); + k--; + } else { + res.append(stack.pollLast()); + } + } + return res.length() == 0 ? "0" : res.toString(); + } +} \ No newline at end of file diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution406.java" b/leetcode_Java/Solution0406.java similarity index 75% rename from "\347\203\255\351\242\230HOT100_Java/Solution406.java" rename to leetcode_Java/Solution0406.java index 7812c49..28373e1 100644 --- "a/\347\203\255\351\242\230HOT100_Java/Solution406.java" +++ b/leetcode_Java/Solution0406.java @@ -1,29 +1,24 @@ -package HOT100; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -// 根据身高重建队列 -public class Solution406 { - public int[][] reconstructQueue(int[][] people) { - if (people.length == 0 || people[0].length == 0) - return new int[0][0]; - - // 身高降序,K升序 - Arrays.sort(people, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]; - } - }); - - // K为索引插入 - List list = new ArrayList<>(); - for (int[] arr : people) { - list.add(arr[1], arr); - } - return list.toArray(new int[list.size()][]); - } -} +// 406. 根据身高重建队列 + + +public class Solution { + public int[][] reconstructQueue(int[][] people) { + if (people.length == 0 || people[0].length == 0) + return new int[0][0]; + + // 身高降序,K升序 + Arrays.sort(people, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]; + } + }); + + // K为索引插入 + List list = new ArrayList<>(); + for (int[] arr : people) { + list.add(arr[1], arr); + } + return list.toArray(new int[list.size()][]); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0407.java b/leetcode_Java/Solution0407.java new file mode 100644 index 0000000..e947246 --- /dev/null +++ b/leetcode_Java/Solution0407.java @@ -0,0 +1,47 @@ +// 407. 接雨水 II + + +/* +优先级队列:外圈到内圈访问,逐渐缩小圈 +1、使用优先级队列存放外圈柱子三元组,即横坐标、纵坐标、高度,升序排序。因为木桶原理,内圈柱子能灌多少水取决于外圈最低柱子的高度 + 访问数组标记柱子是否访问过,访问过则跳过 +2、初始化,将外圈柱子三元组存入队列,并标记已访问 +3、当队列不为空时,队列弹出元素为外圈最低柱子,遍历访问最低柱子的上下左右四个方向的柱子。四个方向的作用在于外圈有四个边界,各取所需访问到内圈柱子。 + 方向数组把上下左右四个坐标压缩成一维数组,灵活获取坐标 +4、因为外圈都被访问了,如果坐标有效,则说明柱子在圈内,所以如果被访问的柱子 坐标有效并且未访问, + 那么再判断外圈最低柱子与圈内柱子的高度差,如果高度差大于0,说明圈内柱子可以灌水体积为高度差,否则不能灌水 +5、被访问过的内圈柱子将作为新的外圈柱子,加入到队列中,高度是外圈柱子与内圈柱子取较高者,并标记已访问 + */ +class Solution { + public int trapRainWater(int[][] heightMap) { + int m = heightMap.length, n = heightMap[0].length; + boolean[][] visited = new boolean[m][n]; + PriorityQueue queue = new PriorityQueue<>((o1, o2) -> o1[2] - o2[2]); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { + queue.offer(new int[] {i, j, heightMap[i][j]}); + visited[i][j] = true; + } + } + } + int res = 0; + int[] dirs = {0, -1, 0, 1, 0}; + while (!queue.isEmpty()) { + int[] minSide = queue.poll(); + for (int k = 0; k < 4; k++) { + int x = minSide[0] + dirs[k]; + int y = minSide[1] + dirs[k + 1]; + if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) { + int heighDiff = minSide[2] - heightMap[x][y]; + if (heighDiff > 0) { + res += heighDiff; + } + queue.offer(new int[] {x, y, Math.max(minSide[2], heightMap[x][y])}); + visited[x][y] = true; + } + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0415.java b/leetcode_Java/Solution0415.java new file mode 100644 index 0000000..fa5b41d --- /dev/null +++ b/leetcode_Java/Solution0415.java @@ -0,0 +1,22 @@ +// 415. 字符串相加 + + +/* +模拟竖式加法,从最低位开始两数相加,和超过10则向高位进一位,其中一个数字遍历结束了则需要补0 + */ +class Solution { + public String addStrings(String num1, String num2) { + int i = num1.length() - 1; + int j = num2.length() - 1; + int carry = 0; + StringBuilder res = new StringBuilder(); + while (i >= 0 || j >= 0 || carry > 0) { + int x = i >= 0 ? num1.charAt(i--) - '0' : 0; + int y = j >= 0 ? num2.charAt(j--) - '0' : 0; + int sum = x + y + carry; + carry = sum / 10; + res.append(sum % 10); + } + return res.reverse().toString(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0416.java b/leetcode_Java/Solution0416.java new file mode 100644 index 0000000..804f815 --- /dev/null +++ b/leetcode_Java/Solution0416.java @@ -0,0 +1,83 @@ +// 416. 分割等和子集 + + +/* +动态规划:0-1背包,必须先物品再背包,且逆序遍历背包 +1、题目:给你一个只包含正整数的非空数组 nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 +2、题目简化:求数组元素能否凑成和为sum(nums)/2 +3、数据校验:数组长度小于2、总和除以2余数不为0、元素最大值大于目标值,则不能分割 +4、定义dp数组:dp[i] 表示数组元素能否凑成和为 i +5、初始化: + 1)一维dp数组扩容:增加和为0这一最小规模的情况,方便初始化 + 2)dp[0] = true; 表示数组元素能凑成和为0,方便后面推导 +6、状态转移方程:dp[i] = dp[i] || dp[i - num]; +7、遍历dp数组填表:第一个for循环遍历数组元素,第二个for循环逆序遍历dp数组的未知位置,根据条件获取dp数组的已知位置, + 根据状态转移方程取已知结果汇总计算未知结果。逆序遍历是因为元素只用一次,如果正序遍历会导致元素重复使用。 +8、返回结果:最后一个状态就是结果 + */ +class Solution { + public boolean canPartition(int[] nums) { + if (nums.length < 2) { + return false; + } + int sum = 0, maxNum = 0; + for (int num : nums) { + sum += num; + maxNum = Math.max(maxNum, num); + } + if (sum % 2 != 0) { + return false; + } + int target = sum / 2; + if (maxNum > target) { + return false; + } + boolean[] dp = new boolean[target + 1]; + dp[0] = true; + for (int num : nums) { + for (int i = target; i >= num; i--) { + dp[i] |= dp[i - num]; + } + } + return dp[target]; + } +} + + +/* +1、问题转化:一堆重量为nums[i],价值也为nums[i]的物品中,能否恰好装满容量为target的背包 +2、定义dp数组:dp[i] 表示容量为i的背包最多能装的物品价值 +3、状态转移方程:dp[i] = Math.max(dp[i], dp[i - num] + num); + ↑ ↑ ↑ + 新状态,容量为i时最大价值 旧状态,不取num的价值 取num的价值 +4、初始化:初始化时默认都为0 +5、遍历dp数组填表:第一个for循环遍历数组元素,第二个for循环逆序遍历dp数组的未知位置,根据条件获取dp数组的已知位置, + 根据状态转移方程取已知结果汇总计算未知结果。逆序遍历是因为元素只用一次,如果正序遍历会导致元素重复使用。 +6、返回结果:判断最后一个状态的值是否为目标值 + */ +class Solution { + public boolean canPartition(int[] nums) { + if (nums.length < 2) { + return false; + } + int sum = 0, maxNum = 0; + for (int num : nums) { + sum += num; + maxNum = Math.max(maxNum, num); + } + if (sum % 2 != 0) { + return false; + } + int target = sum / 2; + if (maxNum > target) { + return false; + } + int[] dp = new int[target + 1]; + for (int num : nums) { + for (int i = target; i >= num; i--) { + dp[i] = Math.max(dp[i], dp[i - num] + num); + } + } + return dp[target] == target; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0437.java b/leetcode_Java/Solution0437.java new file mode 100644 index 0000000..3956741 --- /dev/null +++ b/leetcode_Java/Solution0437.java @@ -0,0 +1,51 @@ +// 437. 路径总和 III + + +/** + * class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + + +/* +递归: +1、计算单个节点的路径数 + 1)方法功能:入参是一个节点、目标和,返回节点值等于目标和的个数 + 2)终止条件:节点为空时返回0 + 3)一个节点处理过程和返回结果:节点值等于目标和 则返回1,否则返回0 + 4)递归调用:左右节点同样需要计算个数,因此调用同样的方法递归处理,获取结果。递归参数目标和累减,减去当前节点值,表示以当前节点开始的路径 + 5)递归顺序:前序遍历,左右节点的计算需要依赖根节点值,即传参减去根节点值的目标和 + 6)使用递归调用结果和返回结果:获取左右节点的个数,全部相加后得到 当前节点开始的路径 且 路径和为targetSum 的路径数 +2、计算所有节点的路径数 + 1)方法功能:入参是一个节点、目标和,返回 该节点开始的路径 且 路径和为targetSum 的路径数 + 2)终止条件:节点为空时返回0 + 3)一个节点处理过程和返回结果:直接调用上个递归函数,计算单个节点的路径数,返回该结果 + 4)递归调用:左右节点同样需要计算 以其开始的路径 且 路径和为targetSum 的路径数,因此调用同样的方法递归处理,获取结果 + 5)递归顺序:前序遍历,实际三者顺序可随意,互不依赖 + 6)使用递归调用结果和返回结果:获取根左右的路径数结果,全部相加后得到所有 路径和为targetSum 的路径数 + */ +class Solution { + public int pathSum(TreeNode root, int targetSum) { + if (root == null) { + return 0; + } + return dfs(root, targetSum) + pathSum(root.left, targetSum) + pathSum(root.right, targetSum); + } + + public int dfs(TreeNode root, int targetSum) { + int res = 0; + if (root == null) { + return res; + } + if (root.val == targetSum) { + res += 1; + } + targetSum -= root.val; + res += dfs(root.left, targetSum) + dfs(root.right, targetSum); + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0438.java b/leetcode_Java/Solution0438.java new file mode 100644 index 0000000..2c7d3b8 --- /dev/null +++ b/leetcode_Java/Solution0438.java @@ -0,0 +1,107 @@ +// 438. 找到字符串中所有字母异位词 + + +/* +滑动窗口 + 数组: +1、s的长度小于p时,不能凑成异位词 +2、因为字符串中的字符全是小写字母,可以用长度为26的数组记录字母出现的次数 +3、设n = len(s), m = len(p)。记录p字符串的字母频次 pCount,和s字符串前m个字母频次 sCount +4、若 pCount 和 sCount 相等,说明两者字母相同,则找到第一个异位词索引 0 +5、以p字符串长度m为滑动窗口大小,继续判断s字符串的字符,向右滑动过程,滑动窗口头部增加一个字母,尾部去掉一个字母,增减次数对应记录到sCount +6、每次滑动后都判断 pCount 和 sCount 是否相等,若相等则新增异位词索引 + +s = "cbaadbac", p = "abca" + +sCount = [2,1,1,...], pCount = [2,1,1,...] +c b a a d b a c +↑_____↑ +==================== +sCount = [2,1,0,1..], pCount = [2,1,1,...] +c b a a d b a c + ↑_____↑ + */ +class Solution { + public List findAnagrams(String s, String p) { + int n = s.length(), m = p.length(); + List res = new ArrayList<>(); + if (n < m) { + return res; + } + int[] sCount = new int[26]; + int[] pCount = new int[26]; + for (int i = 0; i < m; i++) { + sCount[s.charAt(i) - 'a']++; + pCount[p.charAt(i) - 'a']++; + } + if (Arrays.equals(sCount, pCount)) { + res.add(0); + } + for (int i = m; i < n; i++) { + sCount[s.charAt(i - m) - 'a']--; + sCount[s.charAt(i) - 'a']++; + if (Arrays.equals(sCount, pCount)) { + res.add(i - m + 1); + } + } + return res; + } +} + + +/* +滑动窗口 + 双指针 +1、定义左右指针,从索引0开始 +2、右指针向右滑动过程,记录 sCount 增加字母次数,当同一字母 sCount 次数大于 pCount,说明窗口内出现了多余的字母,需要移除, + 于是左指针向右滑动,缩小窗口范围,并记录 sCount 减少字母次数,直到该字母次数合法 +3、每次 右指针扩大窗口 和 左指针缩小窗口 操作结束后,窗口内的字母都是符合p要求的字母,判断一下窗口大小是否等于p的长度,是则说明窗口内字母凑齐,是异位词,记录起始索引 + +s = "cbaebabacd", p = "abc" + +sCount = [1,1,1,0,...], pCount = [1,1,1,0,...] + c b a d a b c d + ↑ ↑ +left right +==================== +sCount = [1,1,1,1,...], pCount = [1,1,1,0,...] + c b a d a b c d + ↑ ↑ +left right +==================== +sCount = [0,0,0,0,...], pCount = [1,1,1,0,...] + c b a d a b c d + ↑ ↑ + right left +==================== +sCount = [1,1,1,0,...], pCount = [1,1,1,0,...] + c b a d a b c d + ↑ ↑ + left right + */ +class Solution { + public List findAnagrams(String s, String p) { + int n = s.length(), m = p.length(); + List res = new ArrayList<>(); + if (n < m) { + return res; + } + int[] sCount = new int[26]; + int[] pCount = new int[26]; + for (int i = 0; i < m; i++) { + pCount[p.charAt(i) - 'a']++; + } + int left = 0, right = 0; + while (right < n) { + int index = s.charAt(right) - 'a'; + sCount[index]++; + while (sCount[index] > pCount[index]) { + sCount[s.charAt(left) - 'a']--; + left++; + } + if (right - left + 1 == m) { + res.add(left); + } + right++; + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0448.java b/leetcode_Java/Solution0448.java new file mode 100644 index 0000000..577bc4f --- /dev/null +++ b/leetcode_Java/Solution0448.java @@ -0,0 +1,81 @@ +// 448. 找到所有数组中消失的数字 + + +// 利用好元素和索引的对应关系 +/* +数组统计个数: +数组存放每个数出现的次数,再遍历数组获取出现次数为0的数,直接用索引表示对应的数更直观简便 + */ +class Solution { + public List findDisappearedNumbers(int[] nums) { + int n = nums.length; + List list = new ArrayList<>(); + int[] count = new int[n + 1]; + for (int num : nums) { + count[num]++; + } + for (int i = 1; i <= n; i++) { + if (count[i] == 0) { + list.add(i); + } + } + return list; + } +} + + +/* +集合过滤出现数字: +1、先把数都存入Set集合中 +2、再遍历[1,n]的数字,如果能加入集合则返回true,否则返回false +3、加入集合说明该数字不存在于数组中,将该数字添加到结果列表 + */ +class Solution { + public List findDisappearedNumbers(int[] nums) { + List list = new ArrayList<>(); + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + for (int i = 1; i <= nums.length; i++) { + if (set.add(i)) { + list.add(i); + } + } + return list; + } +} + + +/* +原地交换,查找不对应的数字: +1、遍历数组每个元素,将该元素交换到对应的正确的索引位置上,遇到待交换的两个元素一样时则跳过继续 +2、遍历数组找出元素跟索引不对应的位置,将丢失的数字添加到结果列表中 + */ +class Solution { + public List findDisappearedNumbers(int[] nums) { + List list = new ArrayList<>(); + int n = nums.length; + int index = 0; + while (index < n) { + if (nums[index] == index + 1) { + index++; + } else { + int targetIndex = nums[index] - 1; + if (nums[index] == nums[targetIndex]) { + index++; + continue; + } + int temp = nums[index]; + nums[index] = nums[targetIndex]; + nums[targetIndex] = temp; + } + } + for (int i = 0; i < n; i++) { + if (nums[i] != i + 1) { + list.add(i + 1); + } + } + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0461.java b/leetcode_Java/Solution0461.java new file mode 100644 index 0000000..9b6cae1 --- /dev/null +++ b/leetcode_Java/Solution0461.java @@ -0,0 +1,60 @@ +// 461. 汉明距离 + + +/* +1、异或运算,记为⊕,当且仅当输入位不同时输出为1,故x^y可将x和y二进制位不同的位置标记为1 +2、内置位计数功能,计算二进制数中1的个数 + */ +class Solution { + public int hammingDistance(int x, int y) { + return Integer.bitCount(x ^ y); + } +} + + +/* +n &= n - 1,该运算将 n 的二进制表示的最后一个 1 变成 0,操作几次说明有几个1 + */ +class Solution { + public int hammingDistance(int x, int y) { + int n = x ^ y, count = 0; + while (n > 0) { + n &= n - 1; + count++; + } + return count; + } +} + + +/* +移位实现位计数,每次用最后一位跟1进行与运算,判断是否为1 + */ +class Solution { + public int hammingDistance(int x, int y) { + int s = x ^ y, count = 0; + while (s > 0) { + count += s & 1; + s >>= 1; + } + return count; + } +} + + +/* +1、每次都统计当前 x 和 y 的最后一位,统计完则将 x 和 y 右移一位 +2、当 x 和 y 的最高一位 1 都被统计过之后,循环结束 + */ +class Solution { + public int hammingDistance(int x, int y) { + int count = 0; + while ((x | y) != 0) { + int a = x & 1, b = y & 1; + count += a ^ b; + x >>= 1; + y >>= 1; + } + return count; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0463.java b/leetcode_Java/Solution0463.java new file mode 100644 index 0000000..7a1e6e8 --- /dev/null +++ b/leetcode_Java/Solution0463.java @@ -0,0 +1,40 @@ +// 463. 岛屿的周长 + + +/* +深度优先搜索: +1、两层for循环遍历二维数组每个位置 +2、当碰到陆地时,通过深度优先搜索往上下左右四个方向扩散陆地 +3、走过的陆地标记为2。当越界时或碰到海水时,返回边长1。当碰到遍历过的陆地,返回0。累加边长得到周长 + */ +class Solution { + public int islandPerimeter(int[][] grid) { + int n = grid.length, m = grid[0].length; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == 1) { + return dfs(grid, row, col); + } + } + } + return 0; + } + + private int dfs(int[][] grid, int row, int col) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return 1; + } + if (grid[row][col] == 0) { + return 1; + } + if (grid[row][col] == 2) { + return 0; + } + grid[row][col] = 2; + return dfs(grid, row - 1, col) + + dfs(grid, row + 1, col) + + dfs(grid, row, col - 1) + + dfs(grid, row, col + 1); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0468.java b/leetcode_Java/Solution0468.java new file mode 100644 index 0000000..be6f546 --- /dev/null +++ b/leetcode_Java/Solution0468.java @@ -0,0 +1,79 @@ +// 468. 验证IP地址 + + +/* +分割校验: +1、判断是否ipv4 + 1)ip长度大于0且尾字符是'.'则返回false + 2)根据'.'分割成数组,注意'.'是转义字符,需要用'\'处理为原字符,'\'也是转义字符所以也要再处理一遍,最终为'\\.' + 3)数组长度不等于4,返回false + 4)子串长度为0或大于3,返回false + 5)子串长度大于1且存在前置0,返回false + 6)子串存在非数字,返回false + 7)子串转化成数字后大于255,返回false + 8)否则返回true +2、判断是否ipv6 + 1)ip长度大于0且尾字符是':'则返回false + 2)根据'.'分割成数组,数组长度不等于8,返回false + 3)子串长度为0或大于4,返回false + 4)子串存在0-9、a-f、A-F以外的字符,返回false + 5)否则返回true + */ +class Solution { + public String validIPAddress(String queryIP) { + if (isValidIPv4(queryIP)) { + return "IPv4"; + } else if (isValidIPv6(queryIP)) { + return "IPv6"; + } else { + return "Neither"; + } + } + + private boolean isValidIPv4(String queryIP) { + if (queryIP.length() > 0 && queryIP.charAt(queryIP.length() - 1) == '.') { + return false; + } + String[] array = queryIP.split("\\."); + if (array.length != 4) { + return false; + } + for (String s: array) { + if (s.length() == 0 || s.length() > 3) { + return false; + } + if (s.length() > 1 && s.charAt(0) == '0') { + return false; + } + int num; + try { + num = Integer.valueOf(s); + } catch (Exception e) { + return false; + } + if (num > 255) { + return false; + } + } + return true; + } + + private boolean isValidIPv6(String queryIP) { + if (queryIP.length() > 0 && queryIP.charAt(queryIP.length() - 1) == ':') { + return false; + } + String[] array = queryIP.split(":"); + if (array.length != 8) { + return false; + } + for (String s : array) { + if (s.length() == 0 || s.length() > 4) { + return false; + } + if (!s.matches("[0-9a-fA-F]+")) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0470.java b/leetcode_Java/Solution0470.java new file mode 100644 index 0000000..496f9f4 --- /dev/null +++ b/leetcode_Java/Solution0470.java @@ -0,0 +1,54 @@ +// 470. 用 Rand7() 实现 Rand10() + + +/** + * The rand7() API is already defined in the parent class SolBase. + * public int rand7(); + * @return a random integer in the range 1 to 7 + */ + + +/* +拒绝采样: +(rand7()-1)*7 等概率产生 0 7 14 21 28 35 42 +rand7()-1 等概率产生 0 1 2 3 4 5 6。这里减1目的是缩小产生数字范围,减少拒绝采样量,增大命中率 +两者相加则等概率产生 0-42,在大的等概率空间中取小范围的数,拒绝采样40-42,剩下 0-39 数量上刚好为 10 的倍数,除以10取余加1就可以得到随机数[1,10] +0-9、10-19、20-29、30-39 + */ +class Solution extends SolBase { + public int rand10() { + while (true) { + int num = (rand7() - 1) * 7 + rand7() - 1; + if (num < 40) { + return num % 10 + 1; + } + } + } +} + + +/* +拒绝采样: +1、去掉最后的1-9,剩下的数都是1-10等概率产生 +2、return公式理解:错误公式 ((a - 1) * 7 + b) % 10,假如刚好是2行3列的10,则会返回0,但最终要求返回[1,10],所以要先b-1,最后再+1 + + b 1 2 3 4 5 6 7 + a + 1 1 2 3 4 5 6 7 + 2 8 9 10 1 2 3 4 + 3 5 6 7 8 9 10 1 + 4 2 3 4 5 6 7 8 + 5 9 10 1 2 3 4 5 + 6 6 7 8 9 10 1 2 + 7 3 4 5 6 7 8 9 + */ +class Solution extends SolBase { + public int rand10() { + while (true) { + int a = rand7(), b = rand7(); + if ((a == 6 && b < 6) || a < 6) { + return ((a - 1) * 7 + b - 1) % 10 + 1; + } + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0474.java b/leetcode_Java/Solution0474.java new file mode 100644 index 0000000..ee1951d --- /dev/null +++ b/leetcode_Java/Solution0474.java @@ -0,0 +1,85 @@ +// 474. 一和零 + + +/* +动态规划,0-1背包,三维dp数组 +1、题目:给你一个二进制字符串数组strs和两个整数m和n。请你找出并返回strs的最大子集的长度,该子集中最多有m个0和n个1。如果x的所有元素也是y的元素,集合x是集合y的子集。 +2、题目简化:把总共的 0 和 1 的个数视为背包的容量,每一个字符串视为装进背包的物品。这道题就可以使用 0-1 背包问题的思路完成,这里的目标值是能放进背包的字符串的数量。 + 求能够使用最多 m个0 和 n个1 的字符串的最大数量 +3、定义dp数组:dp[k][i][j] 表示字符串数组的 前k个字符串 能够使用最多 i个0 和 j个1 的字符串的最大数量。 +4、初始化: + 1)三维dp数组扩容:增加 空字符串、0个0、0个1 这一最小规模的情况 + 2)创建三维dp数组时默认初始化为0,dp[0][i][j] = 0 表示前0个字符串是空字符串,能够使用最多i个0和j个1的字符串的最大数量为0 +5、状态转移方程: + if (i >= zero && j >= one) dp[k][i][j] = Math.max(dp[k - 1][i][j], dp[k - 1][i - zero][j - one] + 1); // 够放,比较“不放”和“放”的最大值 + else dp[k][i][j] = dp[k - 1][i][j]; // 不够放,直接取“不放”的值 +6、遍历dp数组填表: + 第一层遍历字符串数组,k从1开始,因为k为0的情况已经初始化好了,并计算当前字符串0和1的个数 + 第二层遍历0的个数,i从0开始,因为“0”的个数可能为0 + 第三次遍历1的个数,j从0开始,因为“1”的个数可能为0 +7、返回结果:最后一个状态就是结果 + */ +class Solution { + public int findMaxForm(String[] strs, int m, int n) { + int len = strs.length; + int[][][] dp = new int[len + 1][m + 1][n + 1]; + for (int k = 1; k <= len; k++) { + int zero = 0, one = 0; + for (char c : strs[k - 1].toCharArray()) { + if (c == '0') zero++; + else one++; + } + for (int i = 0; i <= m; i++) { + for (int j = 0; j <= n; j++) { + if (i >= zero && j >= one) { + dp[k][i][j] = Math.max(dp[k - 1][i][j], dp[k - 1][i - zero][j - one] + 1); + } else { + dp[k][i][j] = dp[k - 1][i][j]; + } + } + } + } + return dp[len][m][n]; + } +} + + +/* +动态规划,0-1背包,二维dp数组。状态压缩,空间优化,滚动数组 +1、定义dp数组:dp[i][j] 表示能够使用最多 i个0 和 j个1 的字符串的最大数量 +2、初始化: + 1)二维dp数组扩容:增加 0个0、0个1 这一最小规模的情况,方便初始化 + 2)创建二维dp数组时默认初始化为0,dp[0][0] = 0 表示能够使用最多 0个0 和 0个1 的字符串的最大数量为0 +3、状态转移方程:dp[i][j] = Math.max(dp[i][j], dp[i - zero][j - one] + 1); + 1)等式右侧 dp[i][j] 表示 前k-1个字符串 能够使用最多 i个0 和 j个1 的字符串的最大数量 + 2)等式右侧 dp[i - zero][j - one] 表示 前k-1个字符串 能够使用最多 i-zero个0 和 j-one个1 的字符串的最大数量,加1 表示在本轮中“放”第k个字符串 刚好使用 i个0 和 j个1 的字符串的最大数量 + 3)等式左侧 dp[i][j] 表示 前k个字符串 能够使用最多 i个0 和 j个1 的字符串的最大数量 +4、遍历dp数组填表 + 1)遍历顺序 + ① 第一层遍历字符串数组,并计算当前字符串0和1的个数 + ② 第二层遍历0的个数,倒序遍历,只遍历 i >= zero 的情况 + ③ 第三层遍历1的个数,倒序遍历,只遍历 j >= one 的情况 + 2)遍历理解 + ① 二维数组是滚动数组,每一轮滚动遍历中,未遍历的表示上一轮的旧状态,正在遍历的表示正在计算的状态,遍历过的表示本轮的新状态 + ② 本轮遍历中,背包容量不够放时,只能选择不放,旧状态就是“不放”,所以只遍历背包容量足够的情况即可(i >= zero && j >= one) + ③ 倒序遍历是为了正确使用旧状态。如果是正序遍历就会在前面覆盖旧状态,求新状态时用到了前面被覆盖过的状态,表示的含义是物品重复使用,属于完全背包 +5、返回结果:最后一个状态就是结果 + */ +class Solution { + public int findMaxForm(String[] strs, int m, int n) { + int[][] dp = new int[m + 1][n + 1]; + for (String str : strs) { + int zero = 0, one = 0; + for (char c : str.toCharArray()) { + if (c == '0') zero++; + else one++; + } + for (int i = m; i >= zero; i--) { + for (int j = n; j >= one; j--) { + dp[i][j] = Math.max(dp[i][j], dp[i - zero][j - one] + 1); + } + } + } + return dp[m][n]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0491.java b/leetcode_Java/Solution0491.java new file mode 100644 index 0000000..d0e0554 --- /dev/null +++ b/leetcode_Java/Solution0491.java @@ -0,0 +1,39 @@ +// 491. 递增子序列 + + +/* +回溯: +1、使用res存放全局结果,使用track存放子结果 +2、调用递归函数,返回结果 +3、定义递归函数: + 1)终止条件:子结果长度大于等于2时,收集子结果 + 2)剪枝条件:使用used集合,判断同一层元素是否已经使用过,使用过则跳过,因为前面的情况会包含当前的情况 + 3)当前元素大于等于子结果中最后一个元素时,进行选择、递归、回溯过程 + */ +class Solution { + private List> res = new ArrayList<>(); + private Deque track = new LinkedList<>(); + + public List> findSubsequences(int[] nums) { + backtrack(nums, 0); + return res; + } + + private void backtrack(int[] nums, int startIndex) { + if (track.size() >= 2) { + res.add(new ArrayList<>(track)); + } + Set used = new HashSet<>(); + for (int i = startIndex; i < nums.length; i++) { + if (used.contains(nums[i])) { + continue; + } + used.add(nums[i]); + if (track.size() == 0 || nums[i] >= track.getLast()) { + track.addLast(nums[i]); + backtrack(nums, i + 1); + track.removeLast(); + } + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0494.java b/leetcode_Java/Solution0494.java new file mode 100644 index 0000000..a19b71e --- /dev/null +++ b/leetcode_Java/Solution0494.java @@ -0,0 +1,136 @@ +// 494. 目标和 + + +/* +回溯: +1、定义全局变量res累加结果个数 +2、调用递归方法,计算累加结果,返回结果 +3、定义递归函数 + 1)方法参数:除了nums、target需要传递使用,还需增加两个参数,index用于遍历遍历数组指定索引,sum用于计算当前和 + 2)终止条件:遍历结束,判断和是否等于目标值,是则res累加 + 3)调用递归:两次调用递归函数,分别处理当前元素加或减的情况 + */ +class Solution { + private int res = 0; + + public int findTargetSumWays(int[] nums, int target) { + backtrack(nums, 0, 0, target); + return res; + } + + private void backtrack(int[] nums, int index, int sum, int target) { + if (index == nums.length) { + if (sum == target) { + res += 1; + } + return; + } + backtrack(nums, index + 1, sum + nums[index], target); + backtrack(nums, index + 1, sum - nums[index], target); + } +} + + +/* +动态规划,0-1背包,二维dp数组 +1、题目解析: + 每个数字都有两种状态:被进行“+”,或者被进行“-”,因此可以将数组分成A和B两个部分:A部分的数字全部进行“+”操作,B部分的数字全部进行“-”操作。 + 设数组的和为sum,A部分的和为sumA,B部分的和为sumB,根据上面的分析,我们可以得出: + sumA + sumB = sum (1) + sumA - sumB = target (2) + 将(1)式与(2)式相加,可以得到:2sumA = sum + target (3) 即:sumA = (sum + target) / 2 + 自此,原问题可以转化为0-1背包问题:有一些物品,第 i 个物品的重量为nums[i],背包的容量为sumA,问:有多少种方式将背包【恰好装满】 +2、数据校验:由公式推导得出的sumA,即bagSize,必须为整数且大于0,否则不能凑出。 +3、定义dp数组:dp[i][j] 表示在前 i 个数字中,凑出和为 j 的组合数,即方法数 + 注意是求组合数,不是排列数,因为数组是有序的,只是在数字前面添加符号,不能改变数字的顺序。 +4、初始化: + 1)二维dp数组扩容:增加 0个数字、和为0 这一最小规模的情况 + 2)dp[i][0] 表示在前i个数字中,凑出和为0的组合数,容量不够放所以选择都不放时和为0,有1种方法,因此dp[0][0] = 1 +5、状态转移方程: + if (j < nums[i - 1]) dp[i][j] = dp[i - 1][j]; // 容量不够放,所以只能选择不放 + else dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]]; // 容量够放,可以将 不放时装满 和 放时装满 的组合数相加 + 不放 放 +6、遍历dp数组填表:先遍历数字,再遍历背包,背包正序遍历。数字应该从第1个数字开始,而背包应该从容量为0开始。 + 因为,题目中指出了nums[i] >=0,即可能为0,因此需要考虑到背包容量也为0的情况。 + 比如,第1个数字为0,背包容量也为0时,有两种选择:选择0 或者 不选,这两种选择都可以填满容量为0的背包 +7、返回结果:最后一个状态就是结果 + +nums=[0,1,2,5],target=4,bagSize=6,行代表数字,列代表背包容量,首列初始化为1,从上到下,从左到右更新 + 0 1 2 3 4 5 6 +x 1 0 0 0 0 0 0 +0 2 0 0 0 0 0 0 +1 2 2 0 0 0 0 0 +2 2 2 2 2 0 0 0 +5 2 2 2 2 0 2 2 + */ +class Solution { + public int findTargetSumWays(int[] nums, int target) { + int n = nums.length; + int sum = 0; + for (int num : nums) { + sum += num; + } + if ((sum + target) % 2 != 0) { + return 0; + } + int bagSize = (sum + target) / 2; + if (bagSize < 0) { + return 0; + } + int[][] dp = new int[n + 1][bagSize + 1]; + for (int i = 0; i <= n; i++) { + dp[i][0] = 1; + } + for (int i = 1; i <= n; i++) { + for (int j = 0; j <= bagSize; j++) { + if (j < nums[i - 1]) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]]; + } + } + } + return dp[n][bagSize]; + } +} + + +/* +动态规划,0-1背包,一维dp数组 +1、题目简化:有一些物品,第 i 个物品的重量为nums[i],背包的容量为sumA,求有多少种方式将背包【恰好装满】 +2、定义dp数组:dp[j] 表示凑出和为 j 的组合数,即方法数 +3、状态转移方程:dp[j] = dp[j] + dp[j - num]; + 1)等式右侧 dp[j] 表示前 i-1 个物品凑出和为 j 的组合数,在本轮中表示“不放”第i个物品就凑出和为j的组合数 + 2)等式右侧 dp[j - num] 表示前 i-1 个物品凑出和为 j-nums[i] 的组合数,在本轮中表示“放”第i个物品刚好凑出和为j的组合数 + 3)等式左侧 dp[j] 表示前 i 个物品凑出和为 j 的组合数,是由“不放”和“放”两种情况下凑出和为j的组合数相加 +4、初始化:dp[0] = 1; 装满容量为0的背包,有1种方法,就是装0件物品 +5、遍历dp数组填表:先遍历数字,再遍历背包,背包倒序遍历 + 1)一维数组是滚动数组,每一轮滚动遍历中,未遍历的表示上一轮的旧状态,正在遍历的表示正在计算的状态,遍历过的表示本轮的新状态 + 2)本轮遍历中,背包容量不够放时,只能选择不放,旧状态就是“不放”,所以只遍历背包容量足够的情况即可(j >= num) + 3)倒序遍历是为了正确使用旧状态。如果是正序遍历就会在前面覆盖旧状态,求新状态时用到了前面被覆盖过的状态,表示的含义是物品重复使用,属于完全背包 +6、返回结果:最后一个状态就是结果 + */ +class Solution { + public int findTargetSumWays(int[] nums, int target) { + int n = nums.length; + int sum = 0; + for (int num : nums) { + sum += num; + } + if ((sum + target) % 2 != 0) { + return 0; + } + int bagSize = (sum + target) / 2; + if (bagSize < 0) { + return 0; + } + int[] dp = new int[bagSize + 1]; + dp[0] = 1; + for (int num : nums) { + for (int j = bagSize; j >= num; j--) { + dp[j] += dp[j - num]; + } + } + return dp[bagSize]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0496.java b/leetcode_Java/Solution0496.java new file mode 100644 index 0000000..f48d277 --- /dev/null +++ b/leetcode_Java/Solution0496.java @@ -0,0 +1,85 @@ +// 496. 下一个更大元素 I + + +/* +暴力: +1、初始化结果数组为-1,表示不存在的情况 +2、两个for循环遍历数组,flag标记表示找到了nums1的x在nums2的位置,再往后遍历时比x大就记录该值 + */ +class Solution { + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + int n = nums1.length, m = nums2.length; + int[] res = new int[n]; + Arrays.fill(res, -1); + for (int i = 0; i < n; i++) { + boolean flag = false; + for (int j = 0; j < m; j++) { + if (nums1[i] == nums2[j]) { + flag = true; + } + if (flag && nums1[i] < nums2[j]) { + res[i] = nums2[j]; + break; + } + } + } + return res; + } +} + + +/* +单调递减栈: +1、栈存放的是元素,因为用不到索引。nums1才需要索引来映射到结果数组 +2、从右到左遍历nums2数组,获取每个元素的下一个更大元素 + 1)栈不为空 且 当前元素大于栈顶元素,则栈顶元素出栈,循环处理,直到当前元素小于栈顶元素,那么栈顶元素就是当前元素的下一个更大元素 + 2)记录当前元素的下一个更大元素到map中,当前元素入栈 +3、遍历nums1数组,直接从map中获取当前元素的下一个更大元素,存入结果数组,返回结果 + */ +class Solution { + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + Map map = new HashMap<>(); + Deque stack = new ArrayDeque<>(); + for (int i = nums2.length - 1; i >= 0; i--) { + while (!stack.isEmpty() && nums2[i] > stack.peek()) { + stack.pop(); + } + map.put(nums2[i], stack.isEmpty() ? -1 : stack.peek()); + stack.push(nums2[i]); + } + int n = nums1.length; + int[] res = new int[n]; + for (int i = 0; i < n; i++) { + res[i] = map.get(nums1[i]); + } + return res; + } +} + + +/* +单调递减栈: +1、栈存放的是元素,因为用不到索引。nums1才需要索引来映射到结果数组 +2、从左到右遍历nums2数组,获取每个元素的下一个更大元素 + 1)栈不为空 且 当前元素大于栈顶元素,则栈顶元素出栈,该栈顶元素的下一个更大元素就是当前元素,记录到map中,循环处理,直到当前元素小于栈顶元素 + 2)当前元素入栈 +3、遍历nums1数组,直接从map中获取当前元素的下一个更大元素,存入结果数组,返回结果 + */ +class Solution { + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + Map map = new HashMap<>(); + Deque stack = new ArrayDeque<>(); + for (int i = 0; i < nums2.length; i++) { + while (!stack.isEmpty() && nums2[i] > stack.peek()) { + map.put(stack.pop(), nums2[i]); + } + stack.push(nums2[i]); + } + int n = nums1.length; + int[] res = new int[n]; + for (int i = 0; i < n; i++) { + res[i] = map.getOrDefault(nums1[i], -1); + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0503.java b/leetcode_Java/Solution0503.java new file mode 100644 index 0000000..c975f53 --- /dev/null +++ b/leetcode_Java/Solution0503.java @@ -0,0 +1,26 @@ +// 503. 下一个更大元素 II + + +/* +单调递减栈: +1、栈存放的是索引,因为需要索引映射到结果数组 +2、由于是循环数组,故将两个数组拼接在一起模拟循环效果,相当于遍历两次数组,下标通过取余映射到数组索引 +3、从左到右遍历数组,获取每个元素的下一个更大元素 + 1)栈不为空 且 当前元素大于栈顶元素,则栈顶元素出栈,该栈顶元素的下一个更大元素就是当前元素,记录到结果数组中,循环处理,直到当前元素小于栈顶元素 + 2)当前元素入栈 + */ +class Solution { + public int[] nextGreaterElements(int[] nums) { + Deque stack = new ArrayDeque<>(); + int n = nums.length; + int[] res = new int[n]; + Arrays.fill(res, -1); + for (int i = 0; i < 2 * n; i++) { + while (!stack.isEmpty() && nums[i % n] > nums[stack.peek()]) { + res[stack.pop()] = nums[i % n]; + } + stack.push(i % n); + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0509.java b/leetcode_Java/Solution0509.java new file mode 100644 index 0000000..f8b64ac --- /dev/null +++ b/leetcode_Java/Solution0509.java @@ -0,0 +1,123 @@ +// 509. 斐波那契数 + + +/* +动态规划:自底向上 +1、题目:斐波那契数(通常用 F(n) 表示)形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。F(0) = 0,F(1) = 1,F(n) = F(n - 1) + F(n - 2),其中 n > 1。给定 n ,请计算 F(n)。 +2、题目简化:求F(n) +3、定义dp数组:dp[i] 表示F(i) +4、初始化:dp[0] = 0, dp[1] = 1 +5、状态转移方程:dp[i] = dp[i-1] + dp[i-2] +6、遍历dp数组填表:一个for循环遍历dp数组的未知位置,根据状态转移方程直接取dp数组几个已知结果计算未知结果 +7、返回结果:最后一个状态就是结果 + */ +class Solution { + public int fib(int n) { + if (n == 0 || n == 1) { + return n; + } + int[] dp = new int[n + 1]; + dp[0] = 0; + dp[1] = 1; + for (int i = 2; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; + } +} + + +/* +递归:自顶向下 + */ +class Solution { + public int fib(int n) { + if (n == 0 || n == 1) { + return n; + } + return fib(n - 1) + fib(n - 2); + } +} + + +/* +递归 + 备忘录 + */ +class Solution { + public int fib(int n) { + int[] memo = new int[n + 1]; + return dfs(memo, n); + } + + private int dfs(int[] memo, int n) { + if (n == 0 || n == 1) { + return n; + } + if (memo[n] != 0) { + return memo[n]; + } + memo[n] = dfs(memo, n - 1) + dfs(memo, n - 2); + return memo[n]; + } +} + + +/* +递归 + 备忘录 + 打印递归树 +1、定义打印函数 +2、定义全局变量count表示层数,层数越多 缩进越多 +3、在“递归函数开头”和“每个return语句之前”添加打印点和输出参数值 +4、函数开头使用“count++”,表示先打印再加1。return语句之前使用“--count”,由于要返回了,需要跟进来时层数一致,所以先减1再打印 + +n = 5 +..n = 4 +....n = 3 +......n = 2 +........n = 1 +........return 1 +........n = 0 +........return 0 +......return 1 +......n = 1 +......return 1 +....return 2 +....n = 2 +....return 1 +..return 3 +..n = 3 +..return 2 +return 5 + */ +public class Solution { + private int count = 0; + + public int fib(int n) { + int[] memo = new int[n + 1]; + return dfs(memo, n); + } + + private int dfs(int[] memo, int n) { + printLevel(count++); + System.out.println("n = " + n); + if (n == 0 || n == 1) { + printLevel(--count); + System.out.println("return " + n); + return n; + } + if (memo[n] != 0) { + printLevel(--count); + System.out.println("return " + memo[n]); + return memo[n]; + } + memo[n] = dfs(memo, n - 1) + dfs(memo, n - 2); + printLevel(--count); + System.out.println("return " + memo[n]); + return memo[n]; + } + + private void printLevel(int count) { + for (int i = 0; i < count; i++) { + System.out.print(".."); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0516.java b/leetcode_Java/Solution0516.java new file mode 100644 index 0000000..7568a5d --- /dev/null +++ b/leetcode_Java/Solution0516.java @@ -0,0 +1,73 @@ +// 516. 最长回文子序列 + + +/* +动态规划: +1、题目简化:求字符串s的最长回文子序列的长度 +2、定义dp数组:dp[l][r] 表示字符串在区间s[l,r]的最长回文子序列的长度 +3、初始化: + 1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)dp[i][i] = 1 表示每个字符的最长回文子序列的长度为1 +4、状态转移方程: + 1)如果s[l] == s[r],即区间首尾两个字符相同,由于l= 0; l--) { + if (s.charAt(l) == s.charAt(r)) { + if (r - l == 1) { + dp[l][r] = 2; + } else { + dp[l][r] = dp[l + 1][r - 1] + 2; + } + res = Math.max(res, dp[l][r]); + } else { + dp[l][r] = Math.max(dp[l + 1][r], dp[l][r - 1]); + } + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0518.java b/leetcode_Java/Solution0518.java new file mode 100644 index 0000000..7a4e893 --- /dev/null +++ b/leetcode_Java/Solution0518.java @@ -0,0 +1,111 @@ +// 518. 零钱兑换 II + + +/* +动态规划:完全背包,二维数组 +1、题目:给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。假设每一种面额的硬币有无限个。 +2、题目简化:求凑成总金额amount的硬币组合数 +3、定义dp数组:dp[i][j] 表示使用前i个硬币,凑成总金额j的硬币组合数 +4、初始化:首行首列 + 1)二维dp数组扩容:增加 没有硬币、总金额0 这一最小规模的情况 + 2)dp[i][0] = 1 表示使用前i个硬币,凑成总金额0的硬币组合数为1,即不用硬币就能凑成 + dp[0][j] = 0 表示使用前0个硬币,凑成总金额j的硬币组合数为0,即没有硬币可以凑成。创建dp数组时已经有默认值 +5、状态转移方程 + if (j - coins[i - 1] >= 0) dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]]; // 金额足够,“不用”和“用”两种情况相加 + else dp[i][j] = dp[i - 1][j]; // 金额不够,只能选择“不用”该硬币 + 注意:dp[i - 1][j - coins[i - 1]] 表示第i个硬币只用一次,属于0-1背包。dp[i][j - coins[i - 1]] 表示第i个硬币重复使用,属于完全背包。 +6、遍历dp数组填表:第一层遍历硬币,第二层遍历金额,都从1开始,正序遍历。两个for循环先后都可以,因为计算当前状态只需要当前行左边的状态和上一行的状态 +7、返回结果:最后一个状态就是结果 + +二维dp更新过程,从左到右,从上到下 +amount = 5, coins = [1, 2, 5] + 0 1 2 3 4 5 +x 1 0 0 0 0 0 +1 1 1 1 1 1 1 +2 1 1 2 2 3 3 +5 1 1 2 2 3 4 + */ +class Solution { + public int change(int amount, int[] coins) { + int n = coins.length; + int[][] dp = new int[n + 1][amount + 1]; + for (int i = 0; i <= n; i++) { + dp[i][0] = 1; + } + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= amount; j++) { + if (j - coins[i - 1] >= 0) { + dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]]; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][amount]; + } +} + + +/* +动态规划:完全背包,一维数组 +1、定义dp数组:dp[i] 表示凑成总金额i的硬币组合数 +2、状态转移方程:dp[i] = dp[i] + dp[i-coin],即所有dp[i-coin]相加 +3、初始化:dp[0] = 1,表示凑成总金额0的硬币组合数为1,即不用硬币,方便后面推导 +4、遍历dp数组填表: + 1)遍历顺序: + ① 第一个for循环遍历硬币数组,第二个for循环遍历dp数组的未知位置,根据条件获取dp数组的已知位置,根据状态转移方程取已知结果汇总计算未知结果 + ② 先物品再背包是计算组合,先背包再物品是计算排列,必须正序遍历背包才能重复使用物品 + 2)遍历理解 + ① 一维数组是滚动数组,每一轮滚动遍历中,未遍历的表示上一轮的旧状态,正在遍历的表示正在计算的状态,遍历过的表示本轮的新状态 + ② 本轮遍历中,金额不够时,只能选择不用硬币,旧状态就是“不用”,所以只遍历金额足够的情况即可(i = coin 开始) +5、返回结果:最后一个状态就是结果 + +一维dp更新过程,从左到右 +amount = 5, coins = [1, 2, 5] +1 1 1 1 1 1 + 2 2 3 3 + 4 + */ +class Solution { + public int change(int amount, int[] coins) { + int[] dp = new int[amount + 1]; + dp[0] = 1; + for (int coin : coins) { + for (int i = coin; i <= amount; i++) { + dp[i] += dp[i - coin]; + } + } + return dp[amount]; + } +} + + +/* +回溯: +1、因为可重复使用,所以当前层选择元素后,下一层的可选剩余集合就是包括当前元素的后半部分剩余集合,防止产生重复组合 +2、定义递归函数 + 1)终止条件,总和等于目标值,存储子结果 + 2)剪枝条件,总和大于目标值,结束 + 3)for循环遍历数组,做选择 → 递归 → 撤销选择,回溯 + */ +class Solution { + private int res = 0; + + public int change(int amount, int[] coins) { + backtrack(0, 0, amount, coins); + return res; + } + + private void backtrack(int count, int startIndex, int amount, int[] coins) { + if (count == amount) { + res++; + return; + } + if (count > amount) { + return; + } + for (int i = startIndex; i < coins.length; i++) { + backtrack(count + coins[i], i, amount, coins); + } + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0538.java b/leetcode_Java/Solution0538.java new file mode 100644 index 0000000..29bd916 --- /dev/null +++ b/leetcode_Java/Solution0538.java @@ -0,0 +1,55 @@ +// 538. 把二叉搜索树转换为累加树 + + +/** + * class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ + + +/* +递归: +1、方法功能:入参是一个节点,将该节点值 加上 比它大的节点值之和,返回该节点 +2、终止条件:节点为空时返回空 +3、一个节点处理过程和返回结果:将该节点值 加上 比它大的节点值之和,返回该节点 +4、递归调用:左右节点同样需要累加,因此调用同样的方法递归处理 +5、递归顺序:反中序遍历,右根左,节点值从大到小遍历,并累加记录到成员变量num。因此要先处理右节点,再处理根节点,最后处理左节点 +6、使用递归调用结果和返回结果:不用接收返回结果,累加处理即可,最后返回根节点 + */ +class Solution { + int num = 0; + + public TreeNode convertBST(TreeNode root) { + if (root == null) { + return null; + } + convertBST(root.right); + root.val += num; + num = root.val; + convertBST(root.left); + return root; + } +} + + +/* +同上 + */ +public class Solution { + int num = 0; + + public TreeNode convertBST(TreeNode root) { + if (root != null) { + convertBST(root.right); + root.val += num; + num = root.val; + convertBST(root.left); + } + return root; + } + +} \ No newline at end of file diff --git a/leetcode_Java/Solution0543.java b/leetcode_Java/Solution0543.java new file mode 100644 index 0000000..114f59b --- /dev/null +++ b/leetcode_Java/Solution0543.java @@ -0,0 +1,99 @@ +// 543. 二叉树的直径 +// 解法类似“110. 平衡二叉树” + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +结论: +1、两个结点路径长度,即两个节点之间边的数目 +2、某个结点作为根节点的最大路径长度 = 左节点的深度 + 右节点的深度 +3、二叉树的直径为 每个节点作为根节点时的最大路径长度中 取最大值 + +递归 + 最大路径长度成员变量 +计算深度递归函数 +1、方法功能:入参是一个节点,返回节点的深度 +2、终止条件:节点为空时返回0 +3、一个节点处理过程和返回结果:节点不为空时返回1 +4、递归调用:左右节点同样需要计算深度,因此调用同样的方法处理,获取结果 +5、递归顺序:后序遍历,当前节点的深度计算依赖左右节点的深度 +6、使用递归调用结果和返回结果 + 1)当前节点的深度 = 1 + max(左节点深度, 右节点深度) + 2)当前节点为根节点的最大路径长度 = 左节点的深度 + 右节点的深度,更新成员变量最大路径长度maxPath,最终最大值即为直径 + */ +class Solution { + int maxPath = 0; + + public int diameterOfBinaryTree(TreeNode root) { + depth(root); + return maxPath; + } + + public int depth(TreeNode node) { + if (node == null) { + return 0; + } + int left = depth(node.left); + int right = depth(node.right); + maxPath = Math.max(left + right, maxPath); + return 1 + Math.max(left, right); + } +} + + +/* +递归 + 记忆存储: +1、计算深度递归函数 + 1)方法功能:入参是一个节点,返回节点的深度 + 2)终止条件:节点为空时返回0 + 3)一个节点处理过程和返回结果:节点不为空时返回1 + 4)递归调用:左右节点同样需要计算深度,因此调用同样的方法处理,获取结果 + 5)递归顺序:后序遍历,当前节点的深度计算依赖左右节点的深度 + 6)使用递归调用结果和返回结果:当前节点的深度 = 1 + max(左节点深度, 右节点深度) + 7)递归结果记忆存储:计算节点的最大路径长度时,会重复计算节点的深度,使用哈希表存储节点对应的深度 {节点:深度},重复调用时可直接获取返回 +2、计算最大路径长度递归函数 + 1)方法功能:入参是一个节点,返回该节点为根节点的最大路径长度 + 2)终止条件:节点为空返回0 + 3)一个节点处理过程和返回结果:当前节点为根节点的最大路径长度 = 左节点的深度 + 右节点的深度 + 4)递归调用:左右节点同样需要计算最大路径长度,因此调用同样的方法处理,获取结果 + 5)递归顺序:前序遍历,当前节点的最大路径长度计算不依赖左右节点的路径长度,三者顺序可随意。可以先计算根节点的最大路径长度,然后计算左节点的最大路径长度,最后计算右节点的最大路径长度 + 6)使用递归调用结果和返回结果:二叉树的直径 = max(根节点的最大路径长度, 左节点的最大路径长度, 右节点的最大路径长度) + */ +class Solution { + Map map = new HashMap<>(); + + public int diameterOfBinaryTree(TreeNode root) { + if (root == null) { + return 0; + } + return Math.max(depth(root.left) + depth(root.right), Math.max(diameterOfBinaryTree(root.left), diameterOfBinaryTree(root.right))); + } + + public int depth(TreeNode root) { + if (root == null) { + return 0; + } + if (map.get(root) != null) { + return map.get(root); + } + int left = depth(root.left); + int right = depth(root.right); + int depth = 1 + Math.max(left, right); + map.put(root, depth); + return depth; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0560.java b/leetcode_Java/Solution0560.java new file mode 100644 index 0000000..d11ace9 --- /dev/null +++ b/leetcode_Java/Solution0560.java @@ -0,0 +1,68 @@ +// 560. 和为 K 的子数组 + + +/* +暴力破解:两层for循环遍历判断所有子数组 + */ +class Solution { + public int subarraySum(int[] nums, int k) { + int n = nums.length, count = 0; + for (int end = 0; end < n; end++) { + int sum = 0; + for (int start = end; start >= 0; start--) { + sum += nums[start]; + if (sum == k) { + count++; + } + } + } + return count; + } +} + + +/* +前缀和 + 暴力破解 + */ +class Solution { + public int subarraySum(int[] nums, int k) { + int n = nums.length, count = 0; + int[] preSum = new int[n + 1]; + for (int i = 0; i < n; i++) { + preSum[i + 1] = preSum[i] + nums[i]; + } + for (int end = 1; end <= n; end++) { + for (int start = 0; start < end; start++) { + if (preSum[end] - preSum[start] == k) { + count++; + } + } + } + return count; + } +} + + +/* +前缀和 + 哈希表: +1、使用HashMap存放 <前缀和, 出现次数> +2、由于前缀和通过HashMap获取,不用在数组中获取,因此用一个变量记录当前前缀和即可 +3、由于 pre[end] - pre[start - 1] = k 则 pre[end] - k = pre[start - 1] + 遍历数组,边累加计算当前前缀和,并判断另一个预期的前缀和是否出现在HashMap中,以及出现次数,可以构成和为 k 的连续子数组,累加个数 +4、累加记录当前前缀和及次数到HashMap中 + */ +class Solution { + public int subarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + map.put(0, 1); + int curPreSum = 0, count = 0; + for (int i = 0; i < nums.length; i++) { + curPreSum += nums[i]; + if (map.containsKey(curPreSum - k)) { + count += map.get(curPreSum - k); + } + map.put(curPreSum, map.getOrDefault(curPreSum, 0) + 1); + } + return count; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0581.java b/leetcode_Java/Solution0581.java new file mode 100644 index 0000000..a41e49d --- /dev/null +++ b/leetcode_Java/Solution0581.java @@ -0,0 +1,67 @@ +// 581. 最短无序连续子数组 + + +/* +排序:拷贝数组并排序,从左右到中间,比较两个数组元素不同的位置,得到无序子数组的左右边界,左右边界差值即为最短无序连续子数组的长度 + */ +class Solution { + public int findUnsortedSubarray(int[] nums) { + if (isSorted(nums)) { + return 0; + } + int n = nums.length; + int[] newNums = Arrays.copyOf(nums, n); + Arrays.sort(newNums); + int left = 0, right = n - 1; + while (nums[left] == newNums[left]) { + left++; + } + while (nums[right] == newNums[right]) { + right--; + } + return right - left + 1; + } + + private boolean isSorted(int[] nums) { + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] > nums[i + 1]) { + return false; + } + } + return true; + } +} + + +/* +1、假设把数组分成三段,左段和右段是标准的升序数组,中段数组虽是无序的,但满足最小值大于等于左段的最大值,最大值小于等于右段的最小值 +2、需要找到中段的左右边界 + 1)从左到右遍历,动态维护当前最大值max,那么最后一个小于max的元素位置就是右边界(如果大于等于max就会归于右段) + 2)从右到左遍历,动态维护当前最小值min,那么最后一个大于min的元素位置就是左边界(如果小于等于min就会归于左段) +3、左右边界差值就是最短无序连续子数组的长度 + + 左段 中段 右段 +1 2 3 4 6 4 7 5 7 4 7 8 9 + ↑ ↑ ↑ ↑ + begin min max end + */ +class Solution { + public int findUnsortedSubarray(int[] nums) { + int n = nums.length; + int min = nums[n - 1], max = nums[0]; + int begin = 0, end = -1; + for (int i = 0; i < n; i++) { + if (nums[i] < max) { + end = i; + } else { + max = nums[i]; + } + if (nums[n - i - 1] > min) { + begin = n - i - 1; + } else { + min = nums[n - i - 1]; + } + } + return end - begin + 1; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0583.java b/leetcode_Java/Solution0583.java new file mode 100644 index 0000000..ddd4827 --- /dev/null +++ b/leetcode_Java/Solution0583.java @@ -0,0 +1,88 @@ +// 583. 两个字符串的删除操作 + + +/* +动态规划: +1、题目简化:求使word1和word2相同的最少删除次数 +2、定义dp数组:dp[i][j] 表示使 word1前i个字符 和 word2前j个字符 相同的最少删除次数 +3、初始化: + 1)二维dp数组扩容:增加空字符串这一最小规模的情况,方便直观初始化 + 2)dp[i][0] = i 表示使 word1前i个字符 和 空字符串 相同的最少删除次数为i + dp[0][j] = j 表示使 空字符 和 word2前j个字符 相同的最少删除次数为j +4、状态转移方程: + 1)如果word1[i] == word2[j],即两个字符串最后一个字符相同,那么不用删除,结果为 word1前i-1个字符 和 word2前j-1个字符 相同的最少删除次数,即 dp[i][j] = dp[i - 1][j - 1]; + 2)如果word1[i] != word2[j],即两个字符串最后一个字符不相同,那么需要一次删除操作,使用之前状态的最少删除次数加1,有两种情况是状态已知且字符最多的 + ① 删除word1[i],即 word1前i-1个字符 和 word2前j个字符 相同的最少删除次数 加1,即 dp[i - 1][j] + 1 + ② 删除word2[j],即 word1前i个字符 和 word2前j-1个字符 相同的最少删除次数 加1,即 dp[i][j - 1] + 1 + 比较这两种情况是因为删除的字符可能是相同的字符,会增加额外的删除操作,两者取最少就得到当前结果,即 dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]); +5、遍历dp数组填表 + 1)两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最少删除次数 + 2)遍历顺序决定了哪些位置是计算过的、是已知状态,外层遍历字符串word1,内层遍历字符串word2。 + 从二维数组角度看,遍历顺序是从上到下,从左到右,所以遍历到(i,j)位置时,其左方、上方、左上方状态都已经遍历计算过了。 + 从两个字符串角度看,两个指针分别指向两个字符串,两者遍历顺序都是从左到右,所以遍历到(i,j)位置时,其左边其他位置都遍历计算过了。 + 所以求 dp[i][j] 时,dp[i - 1][j - 1]、dp[i - 1][j]、dp[i][j - 1] 都是已知状态了 +6、返回结果:最后一个状态就是结果 + +word1 = "leetcode", word2 = "letgo", minDistance = 5 + '' l e t g o +'' 0 1 2 3 4 5 +l 1 0 1 2 3 4 +e 2 1 0 1 2 3 +e 3 2 1 2 3 4 +t 4 3 2 1 2 3 +c 5 4 3 2 3 4 +o 6 5 4 3 4 3 +d 7 6 5 4 5 4 +e 8 7 6 5 6 5 + + word1[i] == word2[j] word1[i] != word2[j] +word1: l e e t c o d e l e e t c o d e + ↑ ↑ + i i +word2: l e t g o l e t g o + ↑ ↑ + j j + */ +class Solution { + public int minDistance(String word1, String word2) { + int n = word1.length(), m = word2.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 0; i <= n; i++) { + dp[i][0] = i; + } + for (int j = 0; j <= m; j++) { + dp[0][j] = j; + } + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (word1.charAt(i - 1) == word2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[n][m]; + } +} + + +/* +问题转化成“1143.最长公共子序列”,两个字符串除了公共部分,剩余的字符就是要删除的次数 + */ +class Solution { + public int minDistance(String word1, String word2) { + int n = word1.length(), m = word2.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (word1.charAt(i - 1) == word2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return n + m - 2 * dp[n][m]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0589.java b/leetcode_Java/Solution0589.java new file mode 100644 index 0000000..fb960b2 --- /dev/null +++ b/leetcode_Java/Solution0589.java @@ -0,0 +1,84 @@ +// 589. N叉树的前序遍历 + + +/* +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; +*/ + + +/* +递归思路: +1、定义数据结构:使用列表成员变量,存储每次递归操作存入的值 +2、递归终止条件:节点为空时返回 +3、单层递归逻辑:把节点的值存入列表 +4、递归逻辑: + 子节点需要与根节点做同样的事,就要调同样的方法,即递归 + 确定递归顺序/遍历顺序,中左右,子节点从左到右 + 每层不需要接收使用递归方法返回值,列表成员变量存储了结果 +================================================== +新模板注释,递归 +节点值加入列表递归函数 +1、方法功能:入参是一个节点,将该节点值加入列表,返回列表 +2、终止条件:节点为空时,返回列表 +3、一个节点处理过程和返回结果:将节点值加入列表,返回列表 +4、递归调用:多个子节点同样需要加入列表,因此调用同样的方法处理 +5、递归顺序:前序遍历,先处理根节点,再处理多个子节点 +6、使用递归调用结果和返回结果:不用接收递归调用结果,节点已经加入列表了,直接返回列表即可 + * */ +class Solution { + public List list = new ArrayList<>(); + public List preorder(Node root) { + if (root == null) { + return list; + } + list.add(root.val); + for (Node node : root.children) { + preorder(node); + } + return list; + } +} + + +/* +* 迭代思路: +* 1、定义数据结构:列表存放节点值,栈按序存放节点 +* 2、遍历条件、操作逻辑: +* 1)节点入栈顺序决定了节点的遍历顺序,栈的后进先出特点,想实现前序遍历,子节点要从右到左入栈,出栈从左到右操作节点,先存储后操作 +* 2)根节点入栈初始化,轮询栈,弹出节点,节点值存入列表,子节点从右到左入栈 +* */ +class Solution { + public List preorder(Node root) { + List list = new ArrayList<>(); + if (root == null) { + return list; + } + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + root = stack.pop(); + list.add(root.val); + List children = root.children; + Collections.reverse(children); + for (Node node : children) { + stack.push(node); + } + } + return list; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0617.java b/leetcode_Java/Solution0617.java new file mode 100644 index 0000000..0fe6d83 --- /dev/null +++ b/leetcode_Java/Solution0617.java @@ -0,0 +1,128 @@ +// 617. 合并二叉树 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归思路: +1、方法功能:入参是两个节点,返回结果是两个节点和的新节点 +2、处理过程:其中一个节点为空时返回另一个结点,都不为空时以两个节点和创建新节点,并返回该新节点 +3、API调用:新的左节点和新的右节点同样需要这个方法功能,直接调用得到结果 +4、使用API调用的返回结果:连接新的左右节点到根节点 +============================================================================== +新模板注释,递归 +1、方法功能:入参是两个节点,将节点值相加,构造成一个节点,返回该节点 +2、终止条件:其中一个节点为空时,返回另一个节点 +3、两个节点处理过程和返回结果:将两个节点值相加,构造成一个节点,返回该节点 +4、递归调用:新树的左右节点同样需要构造,因此调用同样的方法递归处理,获取结果 +5、递归顺序:前序遍历,要先构造根节点,再构造左右节点 +6、使用递归调用结果和返回结果:获取构造出来的左右节点,将其与根节点连接,返回根节点 + */ +class Solution { + public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null) { + return root2; + } + if (root2 == null) { + return root1; + } + TreeNode root = new TreeNode(root1.val + root2.val); + root.left = mergeTrees(root1.left, root2.left); + root.right = mergeTrees(root1.right, root2.right); + return root; + } +} + + +/* +迭代: +1、使用队列逐层存放两棵树的节点,每次弹出两个节点来处理,进行值相加、存入下一层节点 +2、只有两个节点都不为空时才会存入队列,才需要判断是否有下一层要处理 +3、直接在root1的树上进行值相加,若对应位置节点为空而root2该位置不为空,则直接赋值过来 + */ +class Solution { + public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null) { + return root2; + } + if (root2 == null) { + return root1; + } + Queue queue = new LinkedList<>(); + queue.offer(root1); + queue.offer(root2); + while (!queue.isEmpty()) { + TreeNode node1 = queue.poll(); + TreeNode node2 = queue.poll(); + node1.val += node2.val; + if (node1.left != null && node2.left != null) { + queue.offer(node1.left); + queue.offer(node2.left); + } + if (node1.right != null && node2.right != null) { + queue.offer(node1.right); + queue.offer(node2.right); + } + if (node1.left == null && node2.left != null) { + node1.left = node2.left; + } + if (node1.right == null && node2.right != null) { + node1.right = node2.right; + } + } + return root1; + } +} + + +/* +迭代:逻辑同上,使用栈存储,节点入栈顺序注意一下即可 + */ +class Solution { + public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null) { + return root2; + } + if (root2 == null) { + return root1; + } + Stack stack = new Stack<>(); + stack.push(root2); + stack.push(root1); + while (!stack.isEmpty()) { + TreeNode node1 = stack.pop(); + TreeNode node2 = stack.pop(); + node1.val += node2.val; + if (node1.left != null && node2.left != null) { + stack.push(node2.left); + stack.push(node1.left); + } + if (node1.right != null && node2.right != null) { + stack.push(node2.right); + stack.push(node1.right); + } + if (node1.left == null && node2.left != null) { + node1.left = node2.left; + } + if (node1.right == null && node2.right != null) { + node1.right = node2.right; + } + } + return root1; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0621.java b/leetcode_Java/Solution0621.java new file mode 100644 index 0000000..21cc3aa --- /dev/null +++ b/leetcode_Java/Solution0621.java @@ -0,0 +1,40 @@ +// 621. 任务调度器 + + +/* +桶填充: +1、统计每个任务的数量,以最大任务数为桶的数量,一行为一个桶 +2、冷却为n,以n+1为桶的容量,因为执行同样的任务时间间隔为n+1,冷却时间内可以执行其他任务 +3、任务填桶,当桶存在空闲空间时,即桶没有填满。不是最后一个桶则存在等待时间,最后一个桶则不存在等待时间,因为任务要结束了。 + 所以“总排队时间t1 = (桶个数 - 1) * (n + 1) + 最后一桶的任务数” +4、当桶不存在空闲空间时,即桶填满了,所有任务都依次不断地在单位时间内执行完成,所以“总排队时间t2 = 任务总数” +5、存在空闲空间时 t1 比较大,不存在空闲空间时 t2 比较大,所以完成所有任务所需要的最短时间为 max(t1, t2) + +A B C +A B C +A B +A B +========= +A B C D +A B C E +A B C F +A B D + */ +class Solution { + public int leastInterval(char[] tasks, int n) { + int[] count = new int[26]; + for (char task : tasks) { + count[task - 'A']++; + } + int maxTask = 0, rest = 0; + for (int i = 0; i < 26; i++) { + if (count[i] > maxTask) { + maxTask = count[i]; + rest = 1; + } else if (count[i] == maxTask) { + rest += 1; + } + } + return Math.max(tasks.length, (maxTask - 1) * (n + 1) + rest); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0647.java b/leetcode_Java/Solution0647.java new file mode 100644 index 0000000..a863972 --- /dev/null +++ b/leetcode_Java/Solution0647.java @@ -0,0 +1,39 @@ +// 647. 回文子串 + + +/* +与“5.最长回文子串”相似。本题是判断子串为回文串则数目加1 +动态规划: +1、问题简化:求字符串s中回文子串的数目 +2、定义dp数组:dp[l][r]表示子串s[l,r]是否为回文子串,l是左区间,r是右区间 +3、初始化: + 1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)boolean数组创建时,默认值是false,只需要标记为true的地方即可。可以初始化dp数组 dp[i][i] = true,表示1个字符是回文 +4、状态转移方程:dp[l][r] = (s[l] == s[r]) and (r - l < 3 or dp[l + 1][r - 1]) + 1)s[l] == s[r] 表示首尾两个字符相等 + 2)r - l < 3 表示去掉首尾后剩余0或1个字符时仍是回文。作用包含了1个字符是回文,所以不用初始化dp数组单个字符为true + 3)dp[l + 1][r - 1] 表示去掉首尾后的区间是否回文 +5、遍历dp数组填表:一个for遍历子串的右区间,另一个for循环遍历子串的左区间,顺序都是从左到右,根据状态转移方程推断计算未知结果并填表 +6、返回结果: + 1)初始数目为字符串长度,即每个字符都是一个回文串 + 2)遍历时是回文串时累加记录回文串数目,最后返回结果 + */ +class Solution { + public int countSubstrings(String s) { + int n = s.length(); + int res = n; + boolean[][] dp = new boolean[n][n]; + for (int i = 0; i < n; i++) { + dp[i][i] = true; + } + for (int r = 1; r < n; r++) { + for (int l = 0; l < r; l++) { + if (s.charAt(l) == s.charAt(r) && (r - l < 3 || dp[l + 1][r - 1])) { + dp[l][r] = true; + res++; + } + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0662.java b/leetcode_Java/Solution0662.java new file mode 100644 index 0000000..1188f4b --- /dev/null +++ b/leetcode_Java/Solution0662.java @@ -0,0 +1,147 @@ +// 662. 二叉树最大宽度 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +位置角度:起始位置为1,某个节点在数组中的位置为i,则其 +1)父节点位置:i/2 +2)左子节点位置:2i +3)右子节点位置:2i+1 + +递归: +1、成员变量最大宽度maxWidth,哈希表map保存每层第一个节点的位置值 {层数:首节点位置} +2、定义递归函数: + 1)方法功能:入参是节点、深度、位置,从map中获取同深度即同层的第一个节点位置,更新计算最大宽度 + 2)终止条件:节点为空时,结束 + 3)递归逻辑:左右节点同样需要计算其所在层的宽度,因此调用同样的方法递归处理 +=============================================================================== +新模板注释,递归 +1、方法功能:入参是节点、层数、节点位置,计算当前层 当前节点与首节点的宽度,更新最大宽度 +2、终止条件:节点为空时,结束 +3、一个节点处理过程和返回结果:map没有当前层首节点位置,则将当前节点位置存入。计算当前层 当前节点与首节点的距离,更新最大宽度 +4、递归调用:左右节点同样需要计算宽度,因此调用同样的方法递归处理 +5、递归顺序:前序遍历,左右节点的 +6、使用递归调用结果和返回结果 + */ +class Solution { + private int maxWidth = 0; + private Map map = new HashMap<>(); + + public int widthOfBinaryTree(TreeNode root) { + dfs(root, 1, 1); + return maxWidth; + } + + private void dfs(TreeNode root, int layer, int pos) { + if (root == null) { + return; + } + map.computeIfAbsent(layer, key -> pos); + maxWidth = Math.max(maxWidth, pos - map.get(layer) + 1); + dfs(root.left, layer + 1, 2 * pos); + dfs(root.right, layer + 1, 2 * pos + 1); + } +} + + +/* +迭代: +1、节点为空时返回0 +2、使用两个队列,节点队列nodeQueue存放节点,位置队列posQueue存放节点的位置值,初始化时加入根节点和位置值到队列中 +3、位置关系:根节点位置为 i,则左节点位置为 2i,有节点位置为 2i+1 +4、层序遍历,记录当前层最左边的位置,遍历更新右边的位置,计算更新当前层宽度,并把下一层的节点和位置值存入队列 +5、每层遍历完后都更新最大宽度,最终得到二叉树的最大宽度 + + 1 + / \ + 2 3 + */ +class Solution { + public int widthOfBinaryTree(TreeNode root) { + if (root == null) { + return 0; + } + Queue nodeQueue = new LinkedList<>(); + Queue posQueue = new LinkedList<>(); + nodeQueue.add(root); + posQueue.add(1); + int maxWidth = 0; + while (!nodeQueue.isEmpty()) { + boolean firstFlag = true; + int left = -1, right = -1, tempWidth = 0; + int size = nodeQueue.size(); + while(size > 0) { + TreeNode node = nodeQueue.poll(); + int pos = posQueue.poll(); + if (firstFlag) { + left = pos; + firstFlag = false; + } + right = pos; + tempWidth = Math.max(tempWidth, right - left + 1); + if (node.left != null) { + nodeQueue.add(node.left); + posQueue.add(2 * pos); + } + if (node.right != null) { + nodeQueue.add(node.right); + posQueue.add(2 * pos + 1); + } + size--; + } + maxWidth = Math.max(maxWidth, tempWidth); + } + return maxWidth; + } +} + + +/* +迭代优化:位置队列posQueue存放的是一层节点的所有位置,直接取最左边和最右边的位置就可以计算当前层的宽度,再更新最大宽度 + */ +class Solution { + public int widthOfBinaryTree(TreeNode root) { + if (root == null) { + return 0; + } + LinkedList nodeQueue = new LinkedList<>(); + LinkedList posQueue = new LinkedList<>(); + nodeQueue.add(root); + posQueue.add(1); + int maxWidth = 0; + while (!nodeQueue.isEmpty()) { + maxWidth = Math.max(maxWidth, posQueue.peekLast() - posQueue.peekFirst() + 1); + int size = nodeQueue.size(); + while(size > 0) { + TreeNode node = nodeQueue.poll(); + int pos = posQueue.poll(); + if (node.left != null) { + nodeQueue.add(node.left); + posQueue.add(2 * pos); + } + if (node.right != null) { + nodeQueue.add(node.right); + posQueue.add(2 * pos + 1); + } + size--; + } + } + return maxWidth; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0674.java b/leetcode_Java/Solution0674.java new file mode 100644 index 0000000..e15983a --- /dev/null +++ b/leetcode_Java/Solution0674.java @@ -0,0 +1,68 @@ +// 674. 最长连续递增序列 + + +/* +动态规划: +题目简化:求数组的最长连续递增子序列的长度 +1、定义dp数组:dp[i] 表示以索引i的元素结尾的最长连续递增子序列的长度 +2、初始化: + 1)一维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)dp[i] = 1 表示每一个位置i的连续递增子序列的长度至少是1 +3、状态转移方程:if (nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1; + 位置i的最长连续递增子序列长度 等于前一位置的最长连续递增子序列长度加1 +4、遍历dp数组填表:一个for循环遍历dp数组的未知位置,根据状态转移方程获取已知结果计算未知结果 +5、返回结果:遍历时比较每个位置结尾时的最长连续递增子序列的长度,并记录最大值,最后返回最大值 + */ +class Solution { + public int findLengthOfLCIS(int[] nums) { + int n = nums.length; + int[] dp = new int[n]; + Arrays.fill(dp, 1); + int res = 1; + for (int i = 1; i < n; i++) { + if (nums[i] > nums[i - 1]) { + dp[i] = dp[i - 1] + 1; + res = Math.max(res, dp[i]); + } + } + return res; + } +} + + +/* +贪心:双指针,遍历数组,记录起始位置,当前元素比前一元素大时 计算连续递增子序列的长度 并保存最大值,否则将当前位置重新作为起始位置,最终返回最长连续递增子序列的长度 + */ +class Solution { + public int findLengthOfLCIS(int[] nums) { + int start = 0; + int res = 1; + for (int i = 1; i < nums.length; i++) { + if (nums[i] > nums[i - 1]) { + res = Math.max(res, i - start + 1); + } else { + start = i; + } + } + return res; + } +} + + +/* +贪心:变量计数 + */ +class Solution { + public int findLengthOfLCIS(int[] nums) { + int count = 1; + int res = 1; + for (int i = 1; i < nums.length; i++) { + if (nums[i] > nums[i - 1]) { + res = Math.max(res, ++count); + } else { + count = 1; + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0695.java b/leetcode_Java/Solution0695.java new file mode 100644 index 0000000..22d4a86 --- /dev/null +++ b/leetcode_Java/Solution0695.java @@ -0,0 +1,39 @@ +// 695. 岛屿的最大面积 + + +/* +深度优先搜索: +1、两层for循环遍历二维数组每个位置 +2、当碰到陆地时,通过深度优先搜索往上下左右四个方向扩散陆地 +3、记录岛屿中陆地的个数。当越界或碰到海水时返回0,碰到陆地时返回1,并将走过的陆地淹没,累加陆地的个数得到岛屿的面积 +4、比较每个岛屿的面积得到最大岛屿面积 + */ +class Solution { + public int maxAreaOfIsland(int[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == 1) { + res = Math.max(res, dfs(grid, row, col)); + } + } + } + return res; + } + + private int dfs(int[][] grid, int row, int col) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return 0; + } + if (grid[row][col] == 0) { + return 0; + } + grid[row][col] = 0; + return 1 + + dfs(grid, row + 1, col) + + dfs(grid, row - 1, col) + + dfs(grid, row, col + 1) + + dfs(grid, row, col - 1); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0698.java b/leetcode_Java/Solution0698.java new file mode 100644 index 0000000..eac7d01 --- /dev/null +++ b/leetcode_Java/Solution0698.java @@ -0,0 +1,64 @@ +// 698. 划分为k个相等的子集 + + +class Solution { + public boolean canPartitionKSubsets(int[] nums, int k) { + // 排除一些基本情况 + if (k > nums.length) { + return false; + } + int sum = 0; + for (int v : nums) { + sum += v; + } + if (sum % k != 0) { + return false; + } + // 使用位图技巧 + int used = 0; + int target = sum / k; + // k 号桶初始什么都没装,从 nums[0] 开始做选择 + return backtrack(k, 0, nums, 0, used, target); + } + + HashMap memo = new HashMap<>(); + + // 方法作用:判断一个桶是否能被装满,即是否有子集和为目标值 + boolean backtrack(int k, int bucket, int[] nums, int start, int used, int target) { + if (k == 0) { + // 所有桶都被装满了,而且 nums 一定全部用完了 + return true; + } + if (bucket == target) { + // 装满了当前桶,递归穷举下一个桶的选择,让下一个桶从 nums[0] 开始选数字 + boolean res = backtrack(k - 1, 0, nums, 0, used, target); + // 缓存结果 + memo.put(used, res); + return res; + } + if (memo.containsKey(used)) { + // 避免冗余计算 + return memo.get(used); + } + for (int i = start; i < nums.length; i++) { + // 剪枝,判断索引 i 的元素是否已使用 + if (((used >> i) & 1) == 1) { + continue; + } + if (nums[i] + bucket > target) { + continue; + } + // 做选择,使第 i 位置为 1,表示索引 i 的元素已使用 + used |= 1 << i; + bucket += nums[i]; + // 递归穷举下一个数字是否装入当前桶 + if (backtrack(k, bucket, nums, i + 1, used, target)) { + return true; + } + // 撤销选择,将第 i 位置为 0,表示索引 i 的元素未使用 + used ^= 1 << i; + bucket -= nums[i]; + } + return false; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0704.java b/leetcode_Java/Solution0704.java new file mode 100644 index 0000000..4339fd1 --- /dev/null +++ b/leetcode_Java/Solution0704.java @@ -0,0 +1,20 @@ +// 704. 二分查找 + + +// 进阶题“33.搜索旋转排序数组” +class Solution { + public int search(int[] nums, int target) { + int left = 0, right = nums.length - 1; + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] == target) { + return mid; + } else if (nums[mid] > target) { + right = mid - 1; + } else { + left = mid + 1; + } + } + return -1; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0707.java b/leetcode_Java/Solution0707.java new file mode 100644 index 0000000..a3a2f17 --- /dev/null +++ b/leetcode_Java/Solution0707.java @@ -0,0 +1,202 @@ +// 707. 设计链表 + + +/** + * Your MyLinkedList object will be instantiated and called as such: + * MyLinkedList obj = new MyLinkedList(); + * int param_1 = obj.get(index); + * obj.addAtHead(val); + * obj.addAtTail(val); + * obj.addAtIndex(index,val); + * obj.deleteAtIndex(index); + */ + + +/* +单链表 + */ +public class ListNode { + int val; + ListNode next; + ListNode(int val) { + this.val = val; + } +} + +class MyLinkedList { + + int size; + ListNode head; + + public MyLinkedList() { + size = 0; + head = new ListNode(0); + } + + public int get(int index) { + if (index < 0 || index >= size) { + return -1; + } + ListNode cur = head; + for (int i = 0; i < index + 1; i++) { + cur = cur.next; + } + return cur.val; + } + + public void addAtHead(int val) { + addAtIndex(0, val); + } + + public void addAtTail(int val) { + addAtIndex(size, val); + } + + public void addAtIndex(int index, int val) { + if (index > size) { + return; + } + if (index < 0) { + index = 0; + } + ListNode cur = head; + for (int i = 0; i < index; i++) { + cur = cur.next; + } + ListNode node = new ListNode(val); + node.next = cur.next; + cur.next = node; + size++; + } + + public void deleteAtIndex(int index) { + if (index < 0 || index >= size) { + return; + } + ListNode cur = head; + for (int i = 0; i < index; i++) { + cur = cur.next; + } + cur.next = cur.next.next; + size--; + } +} + + +/* +双链表 + */ +public class ListNode { + int val; + ListNode next; + ListNode prev; + ListNode(int val) { + this.val = val; + } +} + +class MyLinkedList { + + int size; + ListNode head; + ListNode tail; + + public MyLinkedList() { + size = 0; + head = new ListNode(0); + tail = new ListNode(0); + head.next = tail; + tail.prev = head; + } + + public int get(int index) { + if (index < 0 || index >= size) { + return -1; + } + ListNode cur; + if (index + 1 < size - index) { + cur = head; + for (int i = 0; i < index + 1; i++) { + cur = cur.next; + } + } else { + cur = tail; + for (int i = 0; i < size - index; i++) { + cur = cur.prev; + } + } + return cur.val; + } + + public void addAtHead(int val) { + ListNode before = head, after = head.next; + ListNode node = new ListNode(val); + node.next = after; + node.prev = before; + before.next = node; + after.prev = node; + size++; + } + + public void addAtTail(int val) { + ListNode before = tail.prev, after = tail; + ListNode node = new ListNode(val); + node.next = after; + node.prev = before; + before.next = node; + after.prev = node; + size++; + } + + public void addAtIndex(int index, int val) { + if (index > size) { + return; + } + if (index < 0) { + index = 0; + } + ListNode before, after; + if (index < size - index) { + before = head; + for (int i = 0; i < index; i++) { + before = before.next; + } + after = before.next; + } else { + after = tail; + for (int i = 0; i < size - index; i++) { + after = after.prev; + } + before = after.prev; + } + ListNode node = new ListNode(val); + node.next = after; + node.prev = before; + before.next = node; + after.prev = node; + size++; + } + + public void deleteAtIndex(int index) { + if (index < 0 || index >= size) { + return; + } + ListNode before, after; + if (index < size - index - 1) { + before = head; + for (int i = 0; i < index; i++) { + before = before.next; + } + after = before.next.next; + } else { + after = tail; + for (int i = 0; i < size - index - 1; i++) { + after = after.prev; + } + before = after.prev.prev; + } + before.next = after; + after.prev = before; + size--; + } +} diff --git a/leetcode_Java/Solution0712.java b/leetcode_Java/Solution0712.java new file mode 100644 index 0000000..72ffe5c --- /dev/null +++ b/leetcode_Java/Solution0712.java @@ -0,0 +1,64 @@ +// 712. 两个字符串的最小ASCII删除和 + + +/* +动态规划: +1、题目简化:求使s1和s2相同的最小ASCII删除和 +2、定义dp数组:dp[i][j] 表示使 s1前i个字符 和 s2前j个字符 相同的最小ASCII删除和 +3、初始化: + 1)二维dp数组扩容:增加空字符串这一最小规模的情况,方便直观初始化 + 2)dp[i][0] = dp[i - 1][0] + s1.charAt(i - 1); 表示使 s1前i个字符 和 空字符串 相同的最小ASCII删除和,逐个累加 + dp[0][j] = dp[0][j - 1] + s2.charAt(j - 1); 表示使 空字符串 和 s2前j个字符 相同的最小ASCII删除和,逐个累加 +4、状态转移方程: + 1)如果s1[i] == s[j],即两个字符串最后一个字符相同,那么不用删除,结果为 s1前i-1个字符 和 s2前j-1个字符 相同的最小ASCII删除和,即 dp[i][j] = dp[i - 1][j - 1]; + 1)如果s1[i] != s[j],即两个字符串最后一个字符不相同,那么需要删除,使用之前状态的最小ASCII删除和 加上 当前被删除字符的ASCII值,有两种情况是状态已知且字符最多的 + ① 删除s1[i],即 s1前i-1个字符 和 s2前j个字符 相同的最小ASCII删除和 加上 当前被删除字符的ASCII值,即 dp[i - 1][j] + s1.charAt(i - 1) + ① 删除s2[j],即 s1前i个字符 和 s2前j-1个字符 相同的最小ASCII删除和 加上 当前被删除字符的ASCII值,即 dp[i][j - 1] + s2.charAt(j - 1) + 比较这两种情况是因为删除的字符可能是相同的字符,会增加额外的删除操作,两者取最少就得到当前结果,即 dp[i][j] = Math.min(dp[i - 1][j] + s1.charAt(i - 1), dp[i][j - 1] + s2.charAt(j - 1)); +5、遍历dp数组填表 + 1)两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最小ASCII删除和 + 2)遍历顺序决定了哪些位置是计算过的、是已知状态,外层遍历字符串s1,内层遍历字符串s2。 + 从二维数组角度看,遍历顺序是从上到下,从左到右,所以遍历到(i,j)位置时,其左方、上方、左上方状态都已经遍历计算过了。 + 从两个字符串角度看,两个指针分别指向两个字符串,两者遍历顺序都是从左到右,所以遍历到(i,j)位置时,其左边其他位置都遍历计算过了。 + 所以求 dp[i][j] 时,dp[i - 1][j - 1]、dp[i - 1][j]、dp[i][j - 1] 都是已知状态了 +6、返回结果:最后一个状态就是结果 + +s1 = "delete", s2 = "leet" + '' l e e t +'' 0 108 209 310 426 +d 100 208 309 410 526 +e 201 309 208 309 425 +l 309 201 302 403 519 +e 410 302 201 302 418 +t 526 418 317 418 302 +e 627 519 418 317 403 + +s1: d e l e t e + ↑ + i +s2: l e e t + ↑ + j + */ +class Solution { + public int minimumDeleteSum(String s1, String s2) { + int n = s1.length(), m = s2.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + dp[i][0] = dp[i - 1][0] + s1.charAt(i - 1); + } + for (int j = 1; j <= m; j++) { + dp[0][j] = dp[0][j - 1] + s2.charAt(j - 1); + } + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (s1.charAt(i - 1) == s2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = Math.min(dp[i - 1][j] + s1.charAt(i - 1), dp[i][j - 1] + s2.charAt(j - 1)); + } + } + } + return dp[n][m]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0714.java b/leetcode_Java/Solution0714.java new file mode 100644 index 0000000..13cdc91 --- /dev/null +++ b/leetcode_Java/Solution0714.java @@ -0,0 +1,34 @@ +// 714. 买卖股票的最佳时机含手续费 + + +/* +与 122.买卖股票的最佳时机II 解法相同,在卖出时扣除手续费即可 + */ +class Solution { + public int maxProfit(int[] prices, int fee) { + int n = prices.length; + int[][] dp = new int[n][2]; + dp[0][0] = 0; + dp[0][1] = -prices[0]; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee); + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); + } + return dp[n - 1][0]; + } +} + + +class Solution { + public int maxProfit(int[] prices, int fee) { + int n = prices.length; + int dp0 = 0, dp1 = -prices[0]; + for (int i = 1; i < n; i++) { + int newDp0 = Math.max(dp0, dp1 + prices[i] - fee); + int newDp1 = Math.max(dp1, dp0 - prices[i]); + dp0 = newDp0; + dp1 = newDp1; + } + return dp0; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0718.java b/leetcode_Java/Solution0718.java new file mode 100644 index 0000000..a2d7b05 --- /dev/null +++ b/leetcode_Java/Solution0718.java @@ -0,0 +1,75 @@ +// 718. 最长重复子数组 + + +/* +动态规划: +1、题目简化:求数组nums1和nums2中最长公共子数组的长度。注意子数组是连续的。(也可以理解成 求两个字符串的最长公共连续子串的长度) +2、定义dp数组:dp[i][j] 表示 nums1第i个元素结尾 和 nums2第j个元素结尾 的最长公共子数组的长度 +3、初始化: + 1)二维dp数组扩容:增加空数组这一最小规模的情况,方便直观初始化 + 2)dp[i][0] = dp[0][j] = 0 表示 空数组 和 任意数组 的最长公共子数组的长度为0。 +4、状态转移方程: + 1)如果 nums1[i] == nums2[j],即两个元素相同时,结果为 nums1第i-1个元素结尾 和 nums2第j-1个元素结尾 的最长公共子数组的长度 加1,即 dp[i][j] = dp[i - 1][j - 1] + 1; + 2)如果 nums1[i] != nums2[j],即两个元素不相同时,以这两个元素结尾的子数组也必然不相同,所以公共子数组的长度为0 +5、遍历dp数组填表: + 1)两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最长公共子数组的长度 + 2)遍历顺序决定了哪些位置是计算过的、是已知状态,外层遍历数组nums1,内层遍历数组nums2。 + 从二维数组角度看,遍历顺序是从上到下,从左到右,所以遍历到(i,j)位置时,其左方、上方、左上方状态都已经遍历计算过了。 + 从两个字符串角度看,两个指针分别指向两个数组,两者遍历顺序都是从左到右,所以遍历到(i,j)位置时,其左边其他位置都遍历计算过了。 + 所以求 dp[i][j] 时,dp[i - 1][j - 1]、dp[i - 1][j]、dp[i][j - 1] 都是已知状态了 +6、返回结果:遍历过程比较并记录最长公共子数组的长度,最后返回结果 + +nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7], findLength = 3 + [] 3 2 1 4 7 +[] 0 0 0 0 0 0 +1 0 0 0 1 0 0 +2 0 0 1 0 0 0 +3 0 1 0 0 0 0 +2 0 0 2 0 0 0 +1 0 0 0 3 0 0 + +nums1: 1 2 3 2 1 + ↑ + i +nums2: 3 2 1 4 7 + ↑ + j + */ +class Solution { + public int findLength(int[] nums1, int[] nums2) { + int n = nums1.length, m = nums2.length, res = 0; + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (nums1[i - 1] == nums2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + res = Math.max(res, dp[i][j]); + } else { + dp[i][j] = 0; + } + } + } + return res; + } +} + + +/* +如果是求“最长重复子序列”,即不要求连续,则解法如下。解法与“1143.最长公共子序列”相同 + */ +class Solution { + public int findLength(int[] nums1, int[] nums2) { + int n = nums1.length, m = nums2.length; + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (nums1[i - 1] == nums2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[n][m]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0739.java b/leetcode_Java/Solution0739.java new file mode 100644 index 0000000..5a2291e --- /dev/null +++ b/leetcode_Java/Solution0739.java @@ -0,0 +1,48 @@ +// 739. 每日温度 + + +/* +暴力:两层for循环遍历数组,查找每个元素右边第一个比它大的元素,计算索引差得到天数i,即为日期left在第i天之后才会有更高的温度 + */ +class Solution { + public int[] dailyTemperatures(int[] temperatures) { + int n = temperatures.length; + int[] res = new int[n]; + for (int left = 0; left < n - 1; left++) { + for (int right = left + 1; right < n; right++) { + if (temperatures[left] < temperatures[right]) { + res[left] = right - left; + break; + } + } + } + return res; + } +} + + +/* +单调递减栈: +1、查找每个元素右边第一个比它大的元素,可以利用单调递减栈的特性 +2、利用栈存放索引,这样既可以通过索引差获取天数,也可以通过索引从数组获取温度值 +3、遍历数组 + 1)栈为空 或 当前温度不大于栈顶温度,则当前索引入栈 + 2)栈不为空 且 当前温度大于栈顶温度,则弹出栈顶索引作为日期左边界,当前索引作为日期右边界,计算日期相差天数i,得到出栈索引日期在第i天之后才会有更高的温度。 + 循环弹出处理,当前温度不大于新栈顶温度,最后当前索引入栈,保证了栈内元素单调递减 +4、剩余栈不为空,说明部分日期后没有更高的温度,天数统一为0,由于数组初始化默认值为0,所以不用处理 + */ +class Solution { + public int[] dailyTemperatures(int[] temperatures) { + int n = temperatures.length; + int[] res = new int[n]; + Deque stack = new ArrayDeque<>(); + for (int right = 0; right < n; right++) { + while (!stack.isEmpty() && temperatures[right] > temperatures[stack.peek()]) { + int left = stack.pop(); + res[left] = right - left; + } + stack.push(right); + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0867.java b/leetcode_Java/Solution0867.java new file mode 100644 index 0000000..639279e --- /dev/null +++ b/leetcode_Java/Solution0867.java @@ -0,0 +1,18 @@ +// 867. 转置矩阵 + + +/* +置换:创建新的矩阵,原矩阵值赋值到新矩阵行列索引交换的位置上 + */ +class Solution { + public int[][] transpose(int[][] matrix) { + int m = matrix.length, n = matrix[0].length; + int[][] res = new int[n][m]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + res[j][i] = matrix[i][j]; + } + } + return res; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution0901.java b/leetcode_Java/Solution0901.java new file mode 100644 index 0000000..c26cc5a --- /dev/null +++ b/leetcode_Java/Solution0901.java @@ -0,0 +1,42 @@ +// 901. 股票价格跨度 + + +/** + * Your StockSpanner object will be instantiated and called as such: + * StockSpanner obj = new StockSpanner(); + * int param_1 = obj.next(price); + */ + + +/* +单调递减栈: +1、栈存放索引,表示日期,方便计算最大连续日数 +2、栈不为空 且 当前价格大于栈顶价格,则弹出栈顶价格 +3、栈为空说明入栈的价格都弹出来了,跨度就是列表的长度 +4、栈不为空,则计算栈顶日期与今天的日期差,得到跨度 + */ +class StockSpanner { + Deque stack; + List list; + + public StockSpanner() { + stack = new ArrayDeque<>(); + list = new ArrayList<>(); + } + + public int next(int price) { + int res = 0; + list.add(price); + while (!stack.isEmpty() && price >= list.get(stack.peek())) { + stack.pop(); + } + if (stack.isEmpty()) { + res = list.size(); + } else { + res = list.size() - 1 - stack.peek(); + } + stack.push(list.size() - 1); + return res; + } +} + diff --git a/leetcode_Java/Solution0968.java b/leetcode_Java/Solution0968.java new file mode 100644 index 0000000..48e326c --- /dev/null +++ b/leetcode_Java/Solution0968.java @@ -0,0 +1,57 @@ +// 968. 监控二叉树 + + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ + + +/* +递归 +1、方法功能:入参是一个节点,返回该节点的监控状态 + 0:该节点无覆盖 1:该节点有摄像头 2:该节点有覆盖 +2、终止条件:节点为空时,表示有覆盖,返回2 +3、一个节点处理过程和返回结果:节点不为空,表示无覆盖,返回0 +4、递归调用:左右节点同样需要获取监控状态,因此调用同样的方法递归处理,获取结果 +5、递归顺序:后序遍历,自底向上进行推导,因为尽量让叶子节点的父节点安装摄像头,这样摄像头的数量才是最少的 +6、使用递归调用结果和返回结果: + 1)左右节点其中一个无覆盖,那么当前节点需要安装摄像头,用于覆盖子节点,返回1 + 2)左右节点其中一个有摄像头,那么当前节点有覆盖,返回2 + 3)左右节点都有覆盖,那么当前节点无覆盖,交给当前节点的父节点处理,返回0 + 4)根节点无覆盖,根节点没有父节点了,要自己处理,所以要安装摄像头 + */ +class Solution { + private int res = 0; + + public int minCameraCover(TreeNode root) { + return dfs(root) == 0 ? res + 1 : res; + } + + private int dfs(TreeNode root) { + if (root == null) { + return 2; + } + int left = dfs(root.left); + int right = dfs(root.right); + if (left == 0 || right == 0) { + res++; + return 1; + } + if (left == 1 || right == 1) { + return 2; + } + return 0; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution1020.java b/leetcode_Java/Solution1020.java new file mode 100644 index 0000000..12e83b7 --- /dev/null +++ b/leetcode_Java/Solution1020.java @@ -0,0 +1,45 @@ +// 1020. 飞地的数量 + + +/* +深度优先搜索: +1、遍历四条边界,将边界的岛屿都淹没,剩下的就是封闭岛屿 +2、两层for循环遍历二维数组每个位置,当碰到陆地时,通过深度优先搜索往上下左右四个方向扩散陆地,将陆地淹没,并累加记录封闭岛屿中陆地的个数 + */ +class Solution { + public int numEnclaves(int[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + for (int row = 0; row < n; row++) { + dfs(grid, row, 0); + dfs(grid, row, m - 1); + } + for (int col = 0; col < m; col++) { + dfs(grid, 0, col); + dfs(grid, n - 1, col); + } + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == 1) { + res += dfs(grid, row, col); + } + } + } + return res; + } + + private int dfs(int[][] grid, int row, int col) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return 0; + } + if (grid[row][col] == 0) { + return 0; + } + grid[row][col] = 0; + return 1 + + dfs(grid, row + 1, col) + + dfs(grid, row - 1, col) + + dfs(grid, row, col + 1) + + dfs(grid, row, col - 1); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution1035.java b/leetcode_Java/Solution1035.java new file mode 100644 index 0000000..ae8b7b7 --- /dev/null +++ b/leetcode_Java/Solution1035.java @@ -0,0 +1,22 @@ +// 1035. 不相交的线 + + +/* +实际就是“1143.最长公共子序列” + */ +class Solution { + public int maxUncrossedLines(int[] nums1, int[] nums2) { + int n = nums1.length, m = nums2.length; + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (nums1[i - 1] == nums2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[n][m]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution1081.java b/leetcode_Java/Solution1081.java new file mode 100644 index 0000000..df018bd --- /dev/null +++ b/leetcode_Java/Solution1081.java @@ -0,0 +1,45 @@ +// 1081. 不同字符的最小子序列 + + +/* +单调递增栈 +实现思路: +1、利用单调递增栈,如果当前字符小于栈顶字符,则栈顶字符出栈,最后当前字符入栈,保证了栈内单调递增,删除了高位上较大的字符,使字典序更小 +2、用inStack数组记录字符是否在栈中,存在则跳过,保证字母不重复 +3、用count数组记录字符的个数,弹出时校验剩余个数,保证字母用一次,使字典序更小 + +算法过程: +1、遍历字符数组 + 1)每遍历一个字符,该字符的剩余个数就减1 + 2)如果字符已经在栈中,那么不能重复添加,需跳过 + 3)栈不为空 且 当前字符小于栈顶字符 且 栈顶字符剩余个数大于0,那么弹出栈顶字符且记录不在栈中。 + 判断 栈顶字符剩余个数大于0 是因为当前在高位弹出该字符能使字典序更小,但要满足每个字符出现一次,所以有剩余后面再加入,当前才可以弹出 + 4)将当前字符入栈,并记录在栈中 +2、栈不为空时,从栈底弹出字符拼凑字符串,返回字符串 + */ +class Solution { + public String smallestSubsequence(String s) { + int[] count = new int[256]; + boolean[] inStack = new boolean[256]; + Deque stack = new ArrayDeque<>(); + for (char c : s.toCharArray()) { + count[c]++; + } + for (char c : s.toCharArray()) { + count[c]--; + if (inStack[c]) { + continue; + } + while (!stack.isEmpty() && c < stack.peek() && count[stack.peek()] > 0) { + inStack[stack.pop()] = false; + } + stack.push(c); + inStack[c] = true; + } + StringBuilder res = new StringBuilder(); + while (!stack.isEmpty()) { + res.append(stack.pollLast()); + } + return res.toString(); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution1143.java b/leetcode_Java/Solution1143.java new file mode 100644 index 0000000..5716eb3 --- /dev/null +++ b/leetcode_Java/Solution1143.java @@ -0,0 +1,57 @@ +// 1143. 最长公共子序列 + + +/* +动态规划: +1、题目简化:求字符串t1和字符串t2的最长公共子序列的长度 +2、定义dp数组:dp[i][j] 表示 t1的前i个字符 和 t2的前j个字符 的最长公共子序列的长度 +3、初始化: + 1)二维dp数组扩容:增加空字符串这一最小规模的情况,方便直观初始化。列表示t1,行表示t2 + 2)dp[i][0] = dp[0][j] = 0 表示空字符串与另一字符串的最长公共子序列的长度为0。创建二维数组时默认为0了 +4、状态转移方程: + 1)如果t1[i] == t2[j],即两个字符串最后一个字符相同,那么结果为 t1的前i-1个字符 和 t2的前j-1个字符 的最长公共子序列的长度加1,即 dp[i][j] = dp[i - 1][j - 1] + 1; + 2)如果t1[i] != t2[j],即两个字符串最后一个字符不相同,那么长度不能增加,只能使用之前状态的最长长度,有两种情况是状态已知且字符最多的 + ① 去掉t1[i],即 t1的前i-1个字符 和 t2的前j个字符 的最长公共子序列的长度,即 dp[i - 1][j] + ② 去掉t2[j],即 t1的前i个字符 和 t2的前j-1个字符 的最长公共子序列的长度,即 dp[i][j - 1] + 比较这两种情况是因为去掉的字符可能刚好是一个公共字符,两者取最大就得到当前结果,即 dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); +5、遍历dp数组填表: + 1)两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最长公共子序列的长度 + 2)遍历顺序决定了哪些位置是计算过的、是已知状态,外层遍历字符串t1,内层遍历字符串t2。 + 从二维数组角度看,遍历顺序是从上到下,从左到右,所以遍历到(i,j)位置时,其左方、上方、左上方状态都已经遍历计算过了。 + 从两个字符串角度看,两个指针分别指向两个字符串,两者遍历顺序都是从左到右,所以遍历到(i,j)位置时,其左边其他位置都遍历计算过了。 + 所以求 dp[i][j] 时,dp[i - 1][j - 1]、dp[i - 1][j]、dp[i][j - 1] 都是已知状态了 +6、返回结果:最后一个状态就是结果 + +t1 = "abcde", t2 = "ace" + '' a c e +'' 0 0 0 0 +a 0 1 1 1 +b 0 1 1 1 +c 0 1 2 2 +d 0 1 2 2 +e 0 1 2 3 + + t1[i] != t2[j] t1[i] == t2[j] +text1: a b c d e a b c d e + ↑ ↑ + i i +text2: a c e a c e + ↑ ↑ + j j + */ +class Solution { + public int longestCommonSubsequence(String text1, String text2) { + int n = text1.length(), m = text2.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + if (text1.charAt(i - 1) == text2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[n][m]; + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution1254.java b/leetcode_Java/Solution1254.java new file mode 100644 index 0000000..f673257 --- /dev/null +++ b/leetcode_Java/Solution1254.java @@ -0,0 +1,45 @@ +// 1254. 统计封闭岛屿的数目 + + +/* +深度优先搜索: +1、遍历四条边界,将边界的岛屿都淹没,剩下的就是封闭岛屿 +2、两层for循环遍历二维数组每个位置,当碰到陆地时,通过深度优先搜索往上下左右四个方向扩散陆地,将陆地淹没,并记录封闭岛屿的个数 + */ +class Solution { + public int closedIsland(int[][] grid) { + int n = grid.length, m = grid[0].length, res = 0; + for (int row = 0; row < n; row++) { + dfs(grid, row, 0); + dfs(grid, row, m - 1); + } + for (int col = 0; col < m; col++) { + dfs(grid, 0, col); + dfs(grid, n - 1, col); + } + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid[row][col] == 0) { + res++; + dfs(grid, row, col); + } + } + } + return res; + } + + private void dfs(int[][] grid, int row, int col) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return; + } + if (grid[row][col] == 1) { + return; + } + grid[row][col] = 1; + dfs(grid, row + 1, col); + dfs(grid, row - 1, col); + dfs(grid, row, col + 1); + dfs(grid, row, col - 1); + } +} \ No newline at end of file diff --git a/leetcode_Java/Solution1905.java b/leetcode_Java/Solution1905.java new file mode 100644 index 0000000..3a8d8e2 --- /dev/null +++ b/leetcode_Java/Solution1905.java @@ -0,0 +1,43 @@ +// 1905. 统计子岛屿 + + +/* +1、两层for循环遍历并比较两个二维数组的每个位置,当grid1是海水且grid2是陆地时,说明grid2的这块陆地不是子岛屿,要淹没掉这块岛屿,遍历结束后剩下的就是子岛屿 +2、两层for循环遍历二维数组grid2,计算岛屿的数量 + */ +class Solution { + public int countSubIslands(int[][] grid1, int[][] grid2) { + int n = grid1.length, m = grid1[0].length, res = 0; + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid1[row][col] == 0 && grid2[row][col] == 1) { + dfs(grid2, row, col); + } + } + } + for (int row = 0; row < n; row++) { + for (int col = 0; col < m; col++) { + if (grid2[row][col] == 1) { + res++; + dfs(grid2, row, col); + } + } + } + return res; + } + + private void dfs(int[][] grid, int row, int col) { + int n = grid.length, m = grid[0].length; + if (row < 0 || col < 0 || row >= n || col >= m) { + return; + } + if (grid[row][col] == 0) { + return; + } + grid[row][col] = 0; + dfs(grid, row + 1, col); + dfs(grid, row - 1, col); + dfs(grid, row, col + 1); + dfs(grid, row, col - 1); + } +} \ No newline at end of file diff --git "a/leetcode/001.\344\270\244\346\225\260\344\271\213\345\222\214.py" "b/leetcode_Python/001.\344\270\244\346\225\260\344\271\213\345\222\214.py" similarity index 96% rename from "leetcode/001.\344\270\244\346\225\260\344\271\213\345\222\214.py" rename to "leetcode_Python/001.\344\270\244\346\225\260\344\271\213\345\222\214.py" index 01183c9..a22e607 100644 --- "a/leetcode/001.\344\270\244\346\225\260\344\271\213\345\222\214.py" +++ "b/leetcode_Python/001.\344\270\244\346\225\260\344\271\213\345\222\214.py" @@ -1,17 +1,17 @@ -# 方法一:暴力破解 -class Solution(object): - def twoSum(self, nums, target): - for i in range(len(nums)-1): - for j in range(i+1, len(nums)): - if target-nums[i]==nums[j]: - return [i, j] - -# 方法二:字典存储值和索引 -class Solution(object): - def twoSum(self, nums, target): - d = {} - for i,num in enumerate(nums): - if target-num in d: - return [d[target-num], i] - else: +# 方法一:暴力破解 +class Solution(object): + def twoSum(self, nums, target): + for i in range(len(nums)-1): + for j in range(i+1, len(nums)): + if target-nums[i]==nums[j]: + return [i, j] + +# 方法二:字典存储值和索引 +class Solution(object): + def twoSum(self, nums, target): + d = {} + for i,num in enumerate(nums): + if target-num in d: + return [d[target-num], i] + else: d[num] = i \ No newline at end of file diff --git "a/leetcode/002.\344\270\244\346\225\260\347\233\270\345\212\240.py" "b/leetcode_Python/002.\344\270\244\346\225\260\347\233\270\345\212\240.py" similarity index 96% rename from "leetcode/002.\344\270\244\346\225\260\347\233\270\345\212\240.py" rename to "leetcode_Python/002.\344\270\244\346\225\260\347\233\270\345\212\240.py" index 970b66c..d19307d 100644 --- "a/leetcode/002.\344\270\244\346\225\260\347\233\270\345\212\240.py" +++ "b/leetcode_Python/002.\344\270\244\346\225\260\347\233\270\345\212\240.py" @@ -1,43 +1,43 @@ -class ListNode(object): - def __init__(self, x): - self.val = x - self.next = None - -# 方法一:转为字符串,相加后再转为链表 -class Solution(object): - def addTwoNumbers(self, l1, l2): - if not l1: - return l2 - if not l2: - return l1 - s1, s2 = '', '' - while l1: - s1 += str(l1.val) - l1 = l1.next - while l2: - s2 += str(l2.val) - l2 = l2.next - s = str(int(s1[::-1]) + int(s2[::-1]))[::-1] - l3 = ListNode(int(s[0])) - l = l3 - for i in s[1:]: - l3.next = ListNode(int(i)) - l3 = l3.next - return l - -# 方法二:使用递归,每次相加一位 -class Solution(object): - def addTwoNumbers(self, l1, l2): - if not l1: - return l2 - if not l2: - return l1 - if l1.val + l2.val < 10: - l = ListNode(l1.val+l2.val) - l.next = self.addTwoNumbers(l1.next, l2.next) - else: - l = ListNode(l1.val+l2.val-10) - temp = ListNode(1) - temp.next = None - l.next = self.addTwoNumbers(l1.next, self.addTwoNumbers(l2.next, temp)) +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + +# 方法一:转为字符串,相加后再转为链表 +class Solution(object): + def addTwoNumbers(self, l1, l2): + if not l1: + return l2 + if not l2: + return l1 + s1, s2 = '', '' + while l1: + s1 += str(l1.val) + l1 = l1.next + while l2: + s2 += str(l2.val) + l2 = l2.next + s = str(int(s1[::-1]) + int(s2[::-1]))[::-1] + l3 = ListNode(int(s[0])) + l = l3 + for i in s[1:]: + l3.next = ListNode(int(i)) + l3 = l3.next + return l + +# 方法二:使用递归,每次相加一位 +class Solution(object): + def addTwoNumbers(self, l1, l2): + if not l1: + return l2 + if not l2: + return l1 + if l1.val + l2.val < 10: + l = ListNode(l1.val+l2.val) + l.next = self.addTwoNumbers(l1.next, l2.next) + else: + l = ListNode(l1.val+l2.val-10) + temp = ListNode(1) + temp.next = None + l.next = self.addTwoNumbers(l1.next, self.addTwoNumbers(l2.next, temp)) return l \ No newline at end of file diff --git "a/leetcode/003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\227\344\270\262.py" "b/leetcode_Python/003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\227\344\270\262.py" similarity index 97% rename from "leetcode/003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\227\344\270\262.py" rename to "leetcode_Python/003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\227\344\270\262.py" index 142f15d..e0365b7 100644 --- "a/leetcode/003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\227\344\270\262.py" +++ "b/leetcode_Python/003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\227\344\270\262.py" @@ -1,11 +1,11 @@ -# 滑动窗口,遇到重复的字符就从该字符下一位开始计算 -class Solution(object): - def lengthOfLongestSubstring(self, s): - d = {} - start = res = 0 - for i, v in enumerate(s): - if v in d: - start = max(start, d[v]+1) - d[v] = i - res = max(res, i-start+1) +# 滑动窗口,遇到重复的字符就从该字符下一位开始计算 +class Solution(object): + def lengthOfLongestSubstring(self, s): + d = {} + start = res = 0 + for i, v in enumerate(s): + if v in d: + start = max(start, d[v]+1) + d[v] = i + res = max(res, i-start+1) return res \ No newline at end of file diff --git "a/leetcode/004.\344\270\244\344\270\252\346\216\222\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" "b/leetcode_Python/004.\344\270\244\344\270\252\346\216\222\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" similarity index 97% rename from "leetcode/004.\344\270\244\344\270\252\346\216\222\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" rename to "leetcode_Python/004.\344\270\244\344\270\252\346\216\222\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" index 9722c72..e6f893c 100644 --- "a/leetcode/004.\344\270\244\344\270\252\346\216\222\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" +++ "b/leetcode_Python/004.\344\270\244\344\270\252\346\216\222\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" @@ -1,10 +1,10 @@ -# 将两个数组相加、排序,再算中位数 -class Solution(object): - def findMedianSortedArrays(self, nums1, nums2): - nums = nums1 + nums2 - nums.sort() - length = len(nums) - if length%2 == 0: - return (nums[length/2-1] + nums[length/2])/2.0 - else: +# 将两个数组相加、排序,再算中位数 +class Solution(object): + def findMedianSortedArrays(self, nums1, nums2): + nums = nums1 + nums2 + nums.sort() + length = len(nums) + if length%2 == 0: + return (nums[length/2-1] + nums[length/2])/2.0 + else: return nums[length/2] \ No newline at end of file diff --git "a/leetcode/007.\345\217\215\350\275\254\346\225\264\346\225\260.py" "b/leetcode_Python/007.\345\217\215\350\275\254\346\225\264\346\225\260.py" similarity index 97% rename from "leetcode/007.\345\217\215\350\275\254\346\225\264\346\225\260.py" rename to "leetcode_Python/007.\345\217\215\350\275\254\346\225\264\346\225\260.py" index 651b3e7..9f4f6a6 100644 --- "a/leetcode/007.\345\217\215\350\275\254\346\225\264\346\225\260.py" +++ "b/leetcode_Python/007.\345\217\215\350\275\254\346\225\264\346\225\260.py" @@ -1,13 +1,13 @@ -# 直接判断正负两种情况 -class Solution(object): - def reverse(self, x): - x = -int(str(x)[::-1][:-1]) if x<0 else int(str(x)[::-1]) - return x if abs(x)<0x7FFFFFFF else 0 - # return x if -2**31<=x<=2**31-1 else 0 - -# 标记正负两种情况 -class Solution(object): - def reverse(self, x): - sign = 1 if x>0 else -1 - x = sign * int(str(abs(x))[::-1]) +# 直接判断正负两种情况 +class Solution(object): + def reverse(self, x): + x = -int(str(x)[::-1][:-1]) if x<0 else int(str(x)[::-1]) + return x if abs(x)<0x7FFFFFFF else 0 + # return x if -2**31<=x<=2**31-1 else 0 + +# 标记正负两种情况 +class Solution(object): + def reverse(self, x): + sign = 1 if x>0 else -1 + x = sign * int(str(abs(x))[::-1]) return x if abs(x)<0x7FFFFFFF else 0 \ No newline at end of file diff --git "a/leetcode/008.\345\255\227\347\254\246\344\270\262\350\275\254\346\225\264\346\225\260.py" "b/leetcode_Python/008.\345\255\227\347\254\246\344\270\262\350\275\254\346\225\264\346\225\260.py" similarity index 96% rename from "leetcode/008.\345\255\227\347\254\246\344\270\262\350\275\254\346\225\264\346\225\260.py" rename to "leetcode_Python/008.\345\255\227\347\254\246\344\270\262\350\275\254\346\225\264\346\225\260.py" index 06ba513..e3d3105 100644 --- "a/leetcode/008.\345\255\227\347\254\246\344\270\262\350\275\254\346\225\264\346\225\260.py" +++ "b/leetcode_Python/008.\345\255\227\347\254\246\344\270\262\350\275\254\346\225\264\346\225\260.py" @@ -1,25 +1,25 @@ -# 逐个条件进行判断 -class Solution(object): - def myAtoi(self, s): - s = s.strip() - if len(s)==0: - return 0 - - s0 = s[0] - res, sign = 0, 1 - if s0=='+' or s0=='-': - if s0=='-': - sign = -1 - s = s[1:] - for i in s: - if i>='0' and i<='9': - res = res*10+int(i) - else: - break - - if res>2147483647: - if sign==1: - return 2147483647 - else: - return -2147483648 +# 逐个条件进行判断 +class Solution(object): + def myAtoi(self, s): + s = s.strip() + if len(s)==0: + return 0 + + s0 = s[0] + res, sign = 0, 1 + if s0=='+' or s0=='-': + if s0=='-': + sign = -1 + s = s[1:] + for i in s: + if i>='0' and i<='9': + res = res*10+int(i) + else: + break + + if res>2147483647: + if sign==1: + return 2147483647 + else: + return -2147483648 return sign*res \ No newline at end of file diff --git "a/leetcode/009.\345\233\236\346\226\207\346\225\260.py" "b/leetcode_Python/009.\345\233\236\346\226\207\346\225\260.py" similarity index 97% rename from "leetcode/009.\345\233\236\346\226\207\346\225\260.py" rename to "leetcode_Python/009.\345\233\236\346\226\207\346\225\260.py" index 15d89db..3a3d262 100644 --- "a/leetcode/009.\345\233\236\346\226\207\346\225\260.py" +++ "b/leetcode_Python/009.\345\233\236\346\226\207\346\225\260.py" @@ -1,3 +1,3 @@ -class Solution(object): - def isPalindrome(self, x): +class Solution(object): + def isPalindrome(self, x): return str(x) == str(x)[::-1] \ No newline at end of file diff --git "a/leetcode/011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" "b/leetcode_Python/011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" similarity index 97% rename from "leetcode/011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" rename to "leetcode_Python/011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" index 2d9c18e..b409535 100644 --- "a/leetcode/011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" +++ "b/leetcode_Python/011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" @@ -1,15 +1,15 @@ -# 双指针移动 -class Solution(object): - def maxArea(self, height): - l, r, m = 0, len(height)-1, 0 - while l < r: - # 记录当前最大面积 - hl, hr = height[l], height[r] - cur = min(hl, hr) * (r-l) - m = max(m, cur) - # 高度较小一端向内移动,获得可能更大的面积 - if hl < hr: - l += 1 - else: - r -= 1 +# 双指针移动 +class Solution(object): + def maxArea(self, height): + l, r, m = 0, len(height)-1, 0 + while l < r: + # 记录当前最大面积 + hl, hr = height[l], height[r] + cur = min(hl, hr) * (r-l) + m = max(m, cur) + # 高度较小一端向内移动,获得可能更大的面积 + if hl < hr: + l += 1 + else: + r -= 1 return m \ No newline at end of file diff --git "a/leetcode/012.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227.py" "b/leetcode_Python/012.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227.py" similarity index 97% rename from "leetcode/012.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227.py" rename to "leetcode_Python/012.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227.py" index 8ad1022..e051dae 100644 --- "a/leetcode/012.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227.py" +++ "b/leetcode_Python/012.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227.py" @@ -1,11 +1,11 @@ -class Solution(object): - def intToRoman(self, num): - res = '' - d = {'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, - 'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1} - # 字典无序,需要先排序,再逆转 - for char, val in sorted(d.items(), key = lambda x: x[1])[::-1]: - while num >= val: - res += char - num -= val +class Solution(object): + def intToRoman(self, num): + res = '' + d = {'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, + 'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1} + # 字典无序,需要先排序,再逆转 + for char, val in sorted(d.items(), key = lambda x: x[1])[::-1]: + while num >= val: + res += char + num -= val return res \ No newline at end of file diff --git "a/leetcode/013.\347\275\227\351\251\254\346\225\260\345\255\227\350\275\254\346\225\264\346\225\260.py" "b/leetcode_Python/013.\347\275\227\351\251\254\346\225\260\345\255\227\350\275\254\346\225\264\346\225\260.py" similarity index 97% rename from "leetcode/013.\347\275\227\351\251\254\346\225\260\345\255\227\350\275\254\346\225\264\346\225\260.py" rename to "leetcode_Python/013.\347\275\227\351\251\254\346\225\260\345\255\227\350\275\254\346\225\264\346\225\260.py" index 4ca979c..c0f445e 100644 --- "a/leetcode/013.\347\275\227\351\251\254\346\225\260\345\255\227\350\275\254\346\225\264\346\225\260.py" +++ "b/leetcode_Python/013.\347\275\227\351\251\254\346\225\260\345\255\227\350\275\254\346\225\264\346\225\260.py" @@ -1,11 +1,11 @@ -# 字符的值比后面小则可以合并,即先减当前数,再加后面数 -class Solution(object): - def romanToInt(self, s): - d = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} - res = 0 - for i in range(len(s)): - if i 0: - y -= 1 - if nums[i] + nums[x] + nums[y] < 0: - x += 1 - # 还原为列表 +# 数组排序后,先固定一个数,再用双指针从头尾向内移动确定另外两个数 +class Solution(object): + def threeSum(self, nums): + n = len(nums) + nums.sort() + res = set() + for i in range(n-2): + x, y = i+1, n-1 + while x < y: + if nums[i] + nums[x] + nums[y] == 0: + # 去重 + res.add((nums[i], nums[x], nums[y])) + x += 1 + y -= 1 + if nums[i] + nums[x] + nums[y] > 0: + y -= 1 + if nums[i] + nums[x] + nums[y] < 0: + x += 1 + # 还原为列表 return [list(l) for l in res] \ No newline at end of file diff --git "a/leetcode/017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" "b/leetcode_Python/017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" similarity index 97% rename from "leetcode/017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" rename to "leetcode_Python/017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" index 0101a3d..90a1307 100644 --- "a/leetcode/017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" +++ "b/leetcode_Python/017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" @@ -1,52 +1,52 @@ -# 回溯 -class Solution(object): - def letterCombinations(self, digits): - if not digits: - return [] - d = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'} - def combine(s, digits): - # 递归终止条件 - if not digits: - res.append(s) - else: - for char in d[digits[0]]: - combine(s + char, digits[1:]) - res = [] - combine('', digits) - return res - - -# 使用变量 -class Solution2(object): - def letterCombinations(self, digits): - if not digits: - return [] - d = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'} - res = [''] - for i in range(len(digits)): - res = [x + y for x in res for y in d[digits[i]]] - return res - -# 递归 -class Solution3(object): - def letterCombinations(self, digits): - if not digits: - return [] - d = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'} - if len(digits) == 1: - return [x for x in d[digits[0]]] - return [x + y for x in d[digits[0]] for y in self.letterCombinations(digits[1:])] - - -# 动态规划 -class Solution4(object): - def letterCombinations(self, digits): - if not digits: - return [] - d = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'} - n = len(digits) - dp = [[] for _ in range(n)] - dp[0] = [x for x in d[digits[0]]] - for i in range(1, n): - dp[i] = [x + y for x in dp[i - 1] for y in d[digits[i]]] +# 回溯 +class Solution(object): + def letterCombinations(self, digits): + if not digits: + return [] + d = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'} + def combine(s, digits): + # 递归终止条件 + if not digits: + res.append(s) + else: + for char in d[digits[0]]: + combine(s + char, digits[1:]) + res = [] + combine('', digits) + return res + + +# 使用变量 +class Solution2(object): + def letterCombinations(self, digits): + if not digits: + return [] + d = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'} + res = [''] + for i in range(len(digits)): + res = [x + y for x in res for y in d[digits[i]]] + return res + +# 递归 +class Solution3(object): + def letterCombinations(self, digits): + if not digits: + return [] + d = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'} + if len(digits) == 1: + return [x for x in d[digits[0]]] + return [x + y for x in d[digits[0]] for y in self.letterCombinations(digits[1:])] + + +# 动态规划 +class Solution4(object): + def letterCombinations(self, digits): + if not digits: + return [] + d = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'} + n = len(digits) + dp = [[] for _ in range(n)] + dp[0] = [x for x in d[digits[0]]] + for i in range(1, n): + dp[i] = [x + y for x in dp[i - 1] for y in d[digits[i]]] return dp[-1] \ No newline at end of file diff --git "a/leetcode/018.\345\233\233\346\225\260\344\271\213\345\222\214.py" "b/leetcode_Python/018.\345\233\233\346\225\260\344\271\213\345\222\214.py" similarity index 97% rename from "leetcode/018.\345\233\233\346\225\260\344\271\213\345\222\214.py" rename to "leetcode_Python/018.\345\233\233\346\225\260\344\271\213\345\222\214.py" index d898e67..7c05996 100644 --- "a/leetcode/018.\345\233\233\346\225\260\344\271\213\345\222\214.py" +++ "b/leetcode_Python/018.\345\233\233\346\225\260\344\271\213\345\222\214.py" @@ -1,23 +1,23 @@ -# 数组排序后,先固定两个数,再用双指针从头尾向内移动确定另外两个数 -class Solution(object): - def fourSum(self, nums, target): - n = len(nums) - nums.sort() - res = set() - for i in range(n-3): - for j in range(i+1, n-2): - l, r = j+1, n-1 - while l < r: - temp = nums[i] + nums[j] + nums[l] + nums[r] - if temp == target: - # 去重 - res.add((nums[i], nums[j], nums[l], nums[r])) - l += 1 - r -= 1 - # 结果比目标值大,右指针左移减小数值 - if temp > target: - r -= 1 - # 结果比目标值小,左指针右移增大数值 - if temp < target: - l += 1 +# 数组排序后,先固定两个数,再用双指针从头尾向内移动确定另外两个数 +class Solution(object): + def fourSum(self, nums, target): + n = len(nums) + nums.sort() + res = set() + for i in range(n-3): + for j in range(i+1, n-2): + l, r = j+1, n-1 + while l < r: + temp = nums[i] + nums[j] + nums[l] + nums[r] + if temp == target: + # 去重 + res.add((nums[i], nums[j], nums[l], nums[r])) + l += 1 + r -= 1 + # 结果比目标值大,右指针左移减小数值 + if temp > target: + r -= 1 + # 结果比目标值小,左指针右移增大数值 + if temp < target: + l += 1 return [list(t) for t in res] \ No newline at end of file diff --git "a/leetcode/019.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271.py" "b/leetcode_Python/019.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271.py" similarity index 97% rename from "leetcode/019.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271.py" rename to "leetcode_Python/019.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271.py" index fc6ed87..43ed2a9 100644 --- "a/leetcode/019.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271.py" +++ "b/leetcode_Python/019.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271.py" @@ -1,14 +1,14 @@ -class Solution(object): - def removeNthFromEnd(self, head, n): - res = left = right = ListNode(0) - res.next = head - # 右指针先走n步 - while n: - right = right.next - n -= 1 - # 左右指针同时向前走,右指针到底时,左指针的下一结点为倒数第N个结点 - while right.next: - left = left.next - right = right.next - left.next = left.next.next +class Solution(object): + def removeNthFromEnd(self, head, n): + res = left = right = ListNode(0) + res.next = head + # 右指针先走n步 + while n: + right = right.next + n -= 1 + # 左右指针同时向前走,右指针到底时,左指针的下一结点为倒数第N个结点 + while right.next: + left = left.next + right = right.next + left.next = left.next.next return res.next \ No newline at end of file diff --git "a/leetcode/020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" "b/leetcode_Python/020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" similarity index 97% rename from "leetcode/020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" rename to "leetcode_Python/020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" index 845dd5d..bd7daf7 100644 --- "a/leetcode/020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" +++ "b/leetcode_Python/020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" @@ -1,15 +1,15 @@ -# 利用栈找对应括号,遇到左括号则进栈,遇到右括号则出栈,判断两个括号是否匹配 -class Solution(object): - def isValid(self, s): - left, right = '([{', '}])' - stack = [] - for i in s: - if i in left: - stack.append(i) - if i in right: - if not stack: - return False - res = stack.pop() - if (i==')' and res!='(') or (i==']' and res!='[') or (i=='}' and res!='{'): - return False +# 利用栈找对应括号,遇到左括号则进栈,遇到右括号则出栈,判断两个括号是否匹配 +class Solution(object): + def isValid(self, s): + left, right = '([{', '}])' + stack = [] + for i in s: + if i in left: + stack.append(i) + if i in right: + if not stack: + return False + res = stack.pop() + if (i==')' and res!='(') or (i==']' and res!='[') or (i=='}' and res!='{'): + return False return not stack \ No newline at end of file diff --git "a/leetcode/021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" "b/leetcode_Python/021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" similarity index 97% rename from "leetcode/021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" rename to "leetcode_Python/021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" index f770c28..5aef946 100644 --- "a/leetcode/021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" +++ "b/leetcode_Python/021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" @@ -1,18 +1,18 @@ -class Solution(object): - def mergeTwoLists(self, l1, l2): - # 一个链表为空则返回另一个链表 - if not l1 or not l2: - return l1 or l2 - # 新链表的头结点 - head = cur = ListNode(0) - while l1 and l2: - if l1.val < l2.val: - cur.next = l1 - l1 = l1.next - else: - cur.next = l2 - l2 = l2.next - cur = cur.next - # 其中一个链表先结束时,将另一个链表剩余部分连接到新链表 - cur.next = l1 if l1 else l2 - return head.next +class Solution(object): + def mergeTwoLists(self, l1, l2): + # 一个链表为空则返回另一个链表 + if not l1 or not l2: + return l1 or l2 + # 新链表的头结点 + head = cur = ListNode(0) + while l1 and l2: + if l1.val < l2.val: + cur.next = l1 + l1 = l1.next + else: + cur.next = l2 + l2 = l2.next + cur = cur.next + # 其中一个链表先结束时,将另一个链表剩余部分连接到新链表 + cur.next = l1 if l1 else l2 + return head.next diff --git "a/leetcode/022.\346\213\254\345\217\267\347\224\237\346\210\220.py" "b/leetcode_Python/022.\346\213\254\345\217\267\347\224\237\346\210\220.py" similarity index 98% rename from "leetcode/022.\346\213\254\345\217\267\347\224\237\346\210\220.py" rename to "leetcode_Python/022.\346\213\254\345\217\267\347\224\237\346\210\220.py" index aea62c4..bf29424 100644 --- "a/leetcode/022.\346\213\254\345\217\267\347\224\237\346\210\220.py" +++ "b/leetcode_Python/022.\346\213\254\345\217\267\347\224\237\346\210\220.py" @@ -1,18 +1,18 @@ -class Solution(object): - def generateParenthesis(self, n): - # 全局数组,存放所有结果 - self.res = [] - # 调用递归函数,设置初值 - self.generate('', 0, 0, n) - return self.res - - # 参数:输出字符串,左括号个数,右括号个数,括号限制个数 - def generate(self, s, left, right, n): - # 终止条件。满足当前条件时,则以下两个条件都不满足,故无需返回,自动终止递归 - if left == n and right == n: - self.res.append(s) - # 剪枝条件。输出字符串和左右括号个数动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - if left < n: - self.generate(s+'(', left+1, right, n) - if right < left: +class Solution(object): + def generateParenthesis(self, n): + # 全局数组,存放所有结果 + self.res = [] + # 调用递归函数,设置初值 + self.generate('', 0, 0, n) + return self.res + + # 参数:输出字符串,左括号个数,右括号个数,括号限制个数 + def generate(self, s, left, right, n): + # 终止条件。满足当前条件时,则以下两个条件都不满足,故无需返回,自动终止递归 + if left == n and right == n: + self.res.append(s) + # 剪枝条件。输出字符串和左右括号个数动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + if left < n: + self.generate(s+'(', left+1, right, n) + if right < left: self.generate(s+')', left, right+1, n) \ No newline at end of file diff --git "a/leetcode/023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" "b/leetcode_Python/023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" similarity index 97% rename from "leetcode/023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" rename to "leetcode_Python/023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" index ca8c5c8..61188ed 100644 --- "a/leetcode/023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" +++ "b/leetcode_Python/023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" @@ -1,33 +1,33 @@ -# 方法一:将所有链表结点存放在数组中,排序后再转化为链表 -class Solution(object): - def mergeKLists(self, lists): - res = [] - for l in lists: - while l: - res.append(l.val) - l = l.next - res.sort() - head = h = ListNode(None) - for i in res: - h.next = ListNode(i) - h = h.next - return head.next - -# 方法二:将每个链表的一个结点放入数组,使用最小堆弹出最小结点,再存入新结点比较 -class Solution(object): - def mergeKLists(self, lists): - import heapq - res = cur = ListNode(-1) - q = [] - # 各链表的头结点 - for head in lists: - if head: - heapq.heappush(q, (head.val, head)) - # 弹出最小结点,若该结点还有下一个结点,则将下一个结点存入数组 - while q: - cur.next = heapq.heappop(q)[1] - cur = cur.next - if cur.next: - heapq.heappush(q, (cur.next.val, cur.next)) - +# 方法一:将所有链表结点存放在数组中,排序后再转化为链表 +class Solution(object): + def mergeKLists(self, lists): + res = [] + for l in lists: + while l: + res.append(l.val) + l = l.next + res.sort() + head = h = ListNode(None) + for i in res: + h.next = ListNode(i) + h = h.next + return head.next + +# 方法二:将每个链表的一个结点放入数组,使用最小堆弹出最小结点,再存入新结点比较 +class Solution(object): + def mergeKLists(self, lists): + import heapq + res = cur = ListNode(-1) + q = [] + # 各链表的头结点 + for head in lists: + if head: + heapq.heappush(q, (head.val, head)) + # 弹出最小结点,若该结点还有下一个结点,则将下一个结点存入数组 + while q: + cur.next = heapq.heappop(q)[1] + cur = cur.next + if cur.next: + heapq.heappush(q, (cur.next.val, cur.next)) + return res.next \ No newline at end of file diff --git "a/leetcode/024.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" "b/leetcode_Python/024.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" similarity index 97% rename from "leetcode/024.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" rename to "leetcode_Python/024.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" index aca8c00..e6fa9bb 100644 --- "a/leetcode/024.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" +++ "b/leetcode_Python/024.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" @@ -1,21 +1,21 @@ -# 递归 -class Solution(object): - def swapPairs(self, head): - if not head or not head.next: - return head - lat = head.next - head.next = self.swapPairs(lat.next) - lat.next = head - return lat - -############## 递归思路 ################### -# 方法作用极简化:先考虑无、1、2个结点的情况。 -# 方法作用描述:参数给一个头结点,两个结点交换后,返回新的头结点。由于剩余部分需要同样操作,使用递归 -class Solution(object): - def swapPairs(self, head): - if not head or not head.next: - return head - lat = head.next - head.next = None - lat.next = head +# 递归 +class Solution(object): + def swapPairs(self, head): + if not head or not head.next: + return head + lat = head.next + head.next = self.swapPairs(lat.next) + lat.next = head + return lat + +############## 递归思路 ################### +# 方法作用极简化:先考虑无、1、2个结点的情况。 +# 方法作用描述:参数给一个头结点,两个结点交换后,返回新的头结点。由于剩余部分需要同样操作,使用递归 +class Solution(object): + def swapPairs(self, head): + if not head or not head.next: + return head + lat = head.next + head.next = None + lat.next = head return lat \ No newline at end of file diff --git "a/leetcode/025.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250.py" "b/leetcode_Python/025.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/025.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250.py" rename to "leetcode_Python/025.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250.py" index 6616814..5699293 100644 --- "a/leetcode/025.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250.py" +++ "b/leetcode_Python/025.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250.py" @@ -1,57 +1,57 @@ -# 方法一 -class Solution(object): - def reverseKGroup(self, head, k): - h = ListNode(-1) - h.next = head - pre = h - cur = head - - while cur: - t = cur - count = 1 - # 遍历k个为一组 - while count target: - return i +class Solution(object): + def searchInsert(self, nums, target): + if target in nums: + return nums.index(target) + for i in range(len(nums)): + if nums[i] > target: + return i return i+1 \ No newline at end of file diff --git "a/leetcode/037.\350\247\243\346\225\260\347\213\254.py" "b/leetcode_Python/037.\350\247\243\346\225\260\347\213\254.py" similarity index 97% rename from "leetcode/037.\350\247\243\346\225\260\347\213\254.py" rename to "leetcode_Python/037.\350\247\243\346\225\260\347\213\254.py" index d104987..9264de6 100644 --- "a/leetcode/037.\350\247\243\346\225\260\347\213\254.py" +++ "b/leetcode_Python/037.\350\247\243\346\225\260\347\213\254.py" @@ -1,42 +1,42 @@ -class Solution(object): - def solveSudoku(self, board): - # 判断当前行列是否可以放数字n - def is_valid(row, col, n): - for i in range(9): - # 判断每一列是否有数字重复 - if board[row][i] == n: - return False - # 判断每一行是否有数字重复 - if board[i][col] == n: - return False - # 判断每一个小方格是否有数字重复 - if board[row // 3 * 3 + i / 3][col // 3 * 3 + i % 3] == n: - return False - return True - - def solve(board): - # 遍历整个表格 - for row in range(9): - for col in range(9): - # 若非空则跳过 - if board[row][col] != '.': - continue - # 在空格处枚举1-9,递归求解 - for n in range(1, 10): - # 判断该数字是否合法,不合法则跳过 - if not is_valid(row, col, str(n)): - continue - # 若合法,则将该数字填入表格 - board[row][col] = str(n) - # 递归判断下一空格,若全部满足条件,返回True - if solve(board): - return True - # 若不满足条件,则回溯,还原初始化设置 - board[row][col] = '.' - # 1-9都不合法,返回False - return False - # 整个表格遍历完成,数字填充完毕,返回True - return True - - solve(board) +class Solution(object): + def solveSudoku(self, board): + # 判断当前行列是否可以放数字n + def is_valid(row, col, n): + for i in range(9): + # 判断每一列是否有数字重复 + if board[row][i] == n: + return False + # 判断每一行是否有数字重复 + if board[i][col] == n: + return False + # 判断每一个小方格是否有数字重复 + if board[row // 3 * 3 + i / 3][col // 3 * 3 + i % 3] == n: + return False + return True + + def solve(board): + # 遍历整个表格 + for row in range(9): + for col in range(9): + # 若非空则跳过 + if board[row][col] != '.': + continue + # 在空格处枚举1-9,递归求解 + for n in range(1, 10): + # 判断该数字是否合法,不合法则跳过 + if not is_valid(row, col, str(n)): + continue + # 若合法,则将该数字填入表格 + board[row][col] = str(n) + # 递归判断下一空格,若全部满足条件,返回True + if solve(board): + return True + # 若不满足条件,则回溯,还原初始化设置 + board[row][col] = '.' + # 1-9都不合法,返回False + return False + # 整个表格遍历完成,数字填充完毕,返回True + return True + + solve(board) return board \ No newline at end of file diff --git "a/leetcode/038.\346\212\245\346\225\260.py" "b/leetcode_Python/038.\346\212\245\346\225\260.py" similarity index 97% rename from "leetcode/038.\346\212\245\346\225\260.py" rename to "leetcode_Python/038.\346\212\245\346\225\260.py" index 99ad66d..8a59cb6 100644 --- "a/leetcode/038.\346\212\245\346\225\260.py" +++ "b/leetcode_Python/038.\346\212\245\346\225\260.py" @@ -1,6 +1,6 @@ -class Solution(object): - def countAndSay(self, n): - res = '1' - for i in range(n-1): - res = ''.join([str(len(list(group))) + key for key, group in itertools.groupby(res)]) +class Solution(object): + def countAndSay(self, n): + res = '1' + for i in range(n-1): + res = ''.join([str(len(list(group))) + key for key, group in itertools.groupby(res)]) return res \ No newline at end of file diff --git "a/leetcode/039.\347\273\204\345\220\210\346\200\273\345\222\214.py" "b/leetcode_Python/039.\347\273\204\345\220\210\346\200\273\345\222\214.py" similarity index 98% rename from "leetcode/039.\347\273\204\345\220\210\346\200\273\345\222\214.py" rename to "leetcode_Python/039.\347\273\204\345\220\210\346\200\273\345\222\214.py" index ef7852f..91de360 100644 --- "a/leetcode/039.\347\273\204\345\220\210\346\200\273\345\222\214.py" +++ "b/leetcode_Python/039.\347\273\204\345\220\210\346\200\273\345\222\214.py" @@ -1,19 +1,19 @@ -class Solution(object): - def combinationSum(self, candidates, target): - # 参数:输出数组,目标数 - def find(output, target): - # 终止条件,将满足条件的结果添加到全局数组,返回空结束当前递归 - if target == 0 and sorted(output) not in res: - res.append(sorted(output)) - return - # 遍历每个元素处理判断 - for candidate in candidates: - new_target = target - candidate - # 剪枝条件,新的目标数若≥0,则可在候选数组继续寻找下一元素 - if new_target >= 0: - # 输出数组和目标值动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - find(output + [candidate], new_target) - - res = [] - find([], target) +class Solution(object): + def combinationSum(self, candidates, target): + # 参数:输出数组,目标数 + def find(output, target): + # 终止条件,将满足条件的结果添加到全局数组,返回空结束当前递归 + if target == 0 and sorted(output) not in res: + res.append(sorted(output)) + return + # 遍历每个元素处理判断 + for candidate in candidates: + new_target = target - candidate + # 剪枝条件,新的目标数若≥0,则可在候选数组继续寻找下一元素 + if new_target >= 0: + # 输出数组和目标值动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + find(output + [candidate], new_target) + + res = [] + find([], target) return res \ No newline at end of file diff --git "a/leetcode/040.\347\273\204\345\220\210\346\200\273\345\222\214 II.py" "b/leetcode_Python/040.\347\273\204\345\220\210\346\200\273\345\222\214 II.py" similarity index 98% rename from "leetcode/040.\347\273\204\345\220\210\346\200\273\345\222\214 II.py" rename to "leetcode_Python/040.\347\273\204\345\220\210\346\200\273\345\222\214 II.py" index 52a8cf7..e496c31 100644 --- "a/leetcode/040.\347\273\204\345\220\210\346\200\273\345\222\214 II.py" +++ "b/leetcode_Python/040.\347\273\204\345\220\210\346\200\273\345\222\214 II.py" @@ -1,16 +1,16 @@ -class Solution(object): - def combinationSum2(self, candidates, target): - # 参数:候选数组,目标值,输出数组 - def find(candidates, target, output): - if target == 0 and sorted(output) not in res: - res.append(sorted(output)) - return - for i in range(len(candidates)): - new_target = target - candidates[i] - if new_target >= 0: - # 候选数组每个数字在每个组合中只能使用一次,故递归时要去除已使用过的数字 - find(candidates[:i] + candidates[i+1:], new_target, output + [candidates[i]]) - - res = [] - find(candidates, target, []) +class Solution(object): + def combinationSum2(self, candidates, target): + # 参数:候选数组,目标值,输出数组 + def find(candidates, target, output): + if target == 0 and sorted(output) not in res: + res.append(sorted(output)) + return + for i in range(len(candidates)): + new_target = target - candidates[i] + if new_target >= 0: + # 候选数组每个数字在每个组合中只能使用一次,故递归时要去除已使用过的数字 + find(candidates[:i] + candidates[i+1:], new_target, output + [candidates[i]]) + + res = [] + find(candidates, target, []) return res \ No newline at end of file diff --git "a/leetcode/043.\345\255\227\347\254\246\344\270\262\347\233\270\344\271\230.py" "b/leetcode_Python/043.\345\255\227\347\254\246\344\270\262\347\233\270\344\271\230.py" similarity index 98% rename from "leetcode/043.\345\255\227\347\254\246\344\270\262\347\233\270\344\271\230.py" rename to "leetcode_Python/043.\345\255\227\347\254\246\344\270\262\347\233\270\344\271\230.py" index b8b5164..0b52ebd 100644 --- "a/leetcode/043.\345\255\227\347\254\246\344\270\262\347\233\270\344\271\230.py" +++ "b/leetcode_Python/043.\345\255\227\347\254\246\344\270\262\347\233\270\344\271\230.py" @@ -1,3 +1,3 @@ -class Solution(object): - def multiply(self, num1, num2): +class Solution(object): + def multiply(self, num1, num2): return str(int(num1)*int(num2)) \ No newline at end of file diff --git "a/leetcode/046.\345\205\250\346\216\222\345\210\227.py" "b/leetcode_Python/046.\345\205\250\346\216\222\345\210\227.py" similarity index 97% rename from "leetcode/046.\345\205\250\346\216\222\345\210\227.py" rename to "leetcode_Python/046.\345\205\250\346\216\222\345\210\227.py" index 156e9c0..69da651 100644 --- "a/leetcode/046.\345\205\250\346\216\222\345\210\227.py" +++ "b/leetcode_Python/046.\345\205\250\346\216\222\345\210\227.py" @@ -1,37 +1,37 @@ -class Solution(object): - def permute(self, nums): - # 参数:输出数组,数组终止长度,原始数组 - def gen(output, n, nums): - # 终止条件,将满足要求的独立结果添加到全局数组,返回空结束当前递归 - if len(output) == n: - res.append(output) - return - # 遍历,判断,递归,使得原始数组中每个元素都有机会成为输出数组的下一个元素 - for num in nums: - # 剪枝条件 - if num not in output: - # 输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - gen(output + [num], n, nums) - - # 全局数组,存放所有结果 - res = [] - # 调用递归函数,设置初值 - gen([], len(nums), nums) - return res - - -class Solution2(object): - def permute(self, nums): - # 参数:输出数组,剩余数组 - def gen(output, nums): - if not nums: - res.append(output) - return - # 遍历,递归,使得剩余数组中每个元素都有机会成为输出数组的下一个元素 - for i in range(len(nums)): - # 输出数组和剩余数组元素动态更新 - gen(output + [nums[i]], nums[:i] + nums[i+1:]) - - res = [] - gen([], nums) +class Solution(object): + def permute(self, nums): + # 参数:输出数组,数组终止长度,原始数组 + def gen(output, n, nums): + # 终止条件,将满足要求的独立结果添加到全局数组,返回空结束当前递归 + if len(output) == n: + res.append(output) + return + # 遍历,判断,递归,使得原始数组中每个元素都有机会成为输出数组的下一个元素 + for num in nums: + # 剪枝条件 + if num not in output: + # 输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + gen(output + [num], n, nums) + + # 全局数组,存放所有结果 + res = [] + # 调用递归函数,设置初值 + gen([], len(nums), nums) + return res + + +class Solution2(object): + def permute(self, nums): + # 参数:输出数组,剩余数组 + def gen(output, nums): + if not nums: + res.append(output) + return + # 遍历,递归,使得剩余数组中每个元素都有机会成为输出数组的下一个元素 + for i in range(len(nums)): + # 输出数组和剩余数组元素动态更新 + gen(output + [nums[i]], nums[:i] + nums[i+1:]) + + res = [] + gen([], nums) return res \ No newline at end of file diff --git "a/leetcode/047.\345\205\250\346\216\222\345\210\227 II.py" "b/leetcode_Python/047.\345\205\250\346\216\222\345\210\227 II.py" similarity index 97% rename from "leetcode/047.\345\205\250\346\216\222\345\210\227 II.py" rename to "leetcode_Python/047.\345\205\250\346\216\222\345\210\227 II.py" index 0eb0008..78fe4a7 100644 --- "a/leetcode/047.\345\205\250\346\216\222\345\210\227 II.py" +++ "b/leetcode_Python/047.\345\205\250\346\216\222\345\210\227 II.py" @@ -1,12 +1,12 @@ -class Solution(object): - def permuteUnique(self, nums): - def find(nums, output): - if not nums and output not in res: - res.append(output) - return - for i in range(len(nums)): - find(nums[:i] + nums[i+1:], output + [nums[i]]) - - res = [] - find(nums, []) +class Solution(object): + def permuteUnique(self, nums): + def find(nums, output): + if not nums and output not in res: + res.append(output) + return + for i in range(len(nums)): + find(nums[:i] + nums[i+1:], output + [nums[i]]) + + res = [] + find(nums, []) return res \ No newline at end of file diff --git "a/leetcode/049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" "b/leetcode_Python/049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" similarity index 97% rename from "leetcode/049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" rename to "leetcode_Python/049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" index 9173890..61b3978 100644 --- "a/leetcode/049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" +++ "b/leetcode_Python/049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" @@ -1,11 +1,11 @@ -# 将排序后字符串相同的字符串添加到字典数组中 -class Solution(object): - def groupAnagrams(self, strs): - d = {} - for s in strs: - S = ''.join(sorted(list(s))) - if S in d: - d[S].append(s) - else: - d[S] = [s] +# 将排序后字符串相同的字符串添加到字典数组中 +class Solution(object): + def groupAnagrams(self, strs): + d = {} + for s in strs: + S = ''.join(sorted(list(s))) + if S in d: + d[S].append(s) + else: + d[S] = [s] return d.values() \ No newline at end of file diff --git a/leetcode/050.Pow(x, n).py b/leetcode_Python/050.Pow(x, n).py similarity index 96% rename from leetcode/050.Pow(x, n).py rename to leetcode_Python/050.Pow(x, n).py index 568416b..6e7105e 100644 --- a/leetcode/050.Pow(x, n).py +++ b/leetcode_Python/050.Pow(x, n).py @@ -1,15 +1,15 @@ -# 折半计算,每次将n缩小一半 -class Solution(object): - def myPow(self, x, n): - if n < 0: - n, x = abs(n), 1/x - res = 1 - while n: - # n为奇数则需要乘一个x - if n % 2: - res *= x - # x翻倍 - x *= x - # n缩小一半 - n //= 2 +# 折半计算,每次将n缩小一半 +class Solution(object): + def myPow(self, x, n): + if n < 0: + n, x = abs(n), 1/x + res = 1 + while n: + # n为奇数则需要乘一个x + if n % 2: + res *= x + # x翻倍 + x *= x + # n缩小一半 + n //= 2 return res \ No newline at end of file diff --git "a/leetcode/051.N\347\232\207\345\220\216.py" "b/leetcode_Python/051.N\347\232\207\345\220\216.py" similarity index 97% rename from "leetcode/051.N\347\232\207\345\220\216.py" rename to "leetcode_Python/051.N\347\232\207\345\220\216.py" index d8050f2..b6ec1e6 100644 --- "a/leetcode/051.N\347\232\207\345\220\216.py" +++ "b/leetcode_Python/051.N\347\232\207\345\220\216.py" @@ -1,72 +1,72 @@ -# 回溯法,判断指定行列位置能否放,能放就递归判断下一行的所有列,不能放就回溯 -class Solution(object): - def solveNQueens(self, n): - # 初始化棋盘和全局数组 - board, res = [['.']*n for _ in range(n)], [] - # 调用递归,设置初值 - self.dfs(board, n, 0, res) - return res - - # 参数:当前棋盘,皇后个数,当前行,全局结果数组 - def dfs(self, board, n, row, res): - # 终止条件,最后一行已放完,满足要求,存入结果数组,返回空结束当前递归,回溯到上一步 - if row == n: - res.append([''.join(i) for i in board]) - return - # 遍历当前行的每一列 - for i in range(n): - # 剪枝条件。判断当前位置能否放,不能放则跳过。若当前行每一列都不能放,则结束当前递归,回溯到上一步 - if not self.canPlace(row, i, n, board): - continue - # 能放则在当前棋盘做标记 - board[row][i] = 'Q' - # 再继续递归判断下一行 - self.dfs(board, n, row+1, res) - # 递归完成后回溯,还原初始化设置,继续遍历判断下一列 - board[row][i] = '.' - - def canPlace(self, row, col, n, board): - for i in range(1, row+1): - # 判断同一列上是否有Q - if board[row-i][col] == 'Q': - return False - # 判断左斜线是否有Q - if col-i >= 0 and board[row-i][col-i] == 'Q': - return False - # 判断右斜线是否有Q - if col+i < n and board[row-i][col+i] == 'Q': - return False - return True - - -class Solution2(object): - def solveNQueens(self, n): - if n == 0: - return [] - res = [] - - # 参数: - def gen(solution, col, diff, add): - row = len(solution) - if len(col) == n: - # line是每一行皇后放的位置 - res.append(['.' * line + 'Q' + '.' * (n - line - 1) for line in solution]) - return - # 遍历当前行的每一列 - for index in range(n): - # 如果当前位置不与其它皇后冲突 - if (index not in col) and (index - row not in diff) and (index + row not in add): - # 则记录当前皇后可到达的位置 - col.add(index) - diff.add(index - row) - add.add(index + row) - # 记录当前皇后可放位置,递归判断下一行 - gen(solution + [index], col, diff, add) - # 递归完成后回溯,还原初始设置,继续遍历判断下一列 - col.remove(index) - diff.remove(index - row) - add.remove(index + row) - - # 三个集合存放皇后能达到的列、左斜线、右斜线 - gen([], set(), set(), set()) +# 回溯法,判断指定行列位置能否放,能放就递归判断下一行的所有列,不能放就回溯 +class Solution(object): + def solveNQueens(self, n): + # 初始化棋盘和全局数组 + board, res = [['.']*n for _ in range(n)], [] + # 调用递归,设置初值 + self.dfs(board, n, 0, res) + return res + + # 参数:当前棋盘,皇后个数,当前行,全局结果数组 + def dfs(self, board, n, row, res): + # 终止条件,最后一行已放完,满足要求,存入结果数组,返回空结束当前递归,回溯到上一步 + if row == n: + res.append([''.join(i) for i in board]) + return + # 遍历当前行的每一列 + for i in range(n): + # 剪枝条件。判断当前位置能否放,不能放则跳过。若当前行每一列都不能放,则结束当前递归,回溯到上一步 + if not self.canPlace(row, i, n, board): + continue + # 能放则在当前棋盘做标记 + board[row][i] = 'Q' + # 再继续递归判断下一行 + self.dfs(board, n, row+1, res) + # 递归完成后回溯,还原初始化设置,继续遍历判断下一列 + board[row][i] = '.' + + def canPlace(self, row, col, n, board): + for i in range(1, row+1): + # 判断同一列上是否有Q + if board[row-i][col] == 'Q': + return False + # 判断左斜线是否有Q + if col-i >= 0 and board[row-i][col-i] == 'Q': + return False + # 判断右斜线是否有Q + if col+i < n and board[row-i][col+i] == 'Q': + return False + return True + + +class Solution2(object): + def solveNQueens(self, n): + if n == 0: + return [] + res = [] + + # 参数: + def gen(solution, col, diff, add): + row = len(solution) + if len(col) == n: + # line是每一行皇后放的位置 + res.append(['.' * line + 'Q' + '.' * (n - line - 1) for line in solution]) + return + # 遍历当前行的每一列 + for index in range(n): + # 如果当前位置不与其它皇后冲突 + if (index not in col) and (index - row not in diff) and (index + row not in add): + # 则记录当前皇后可到达的位置 + col.add(index) + diff.add(index - row) + add.add(index + row) + # 记录当前皇后可放位置,递归判断下一行 + gen(solution + [index], col, diff, add) + # 递归完成后回溯,还原初始设置,继续遍历判断下一列 + col.remove(index) + diff.remove(index - row) + add.remove(index + row) + + # 三个集合存放皇后能达到的列、左斜线、右斜线 + gen([], set(), set(), set()) return res \ No newline at end of file diff --git "a/leetcode/053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" "b/leetcode_Python/053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" similarity index 96% rename from "leetcode/053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" rename to "leetcode_Python/053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" index fb8d22a..4a1a76c 100644 --- "a/leetcode/053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" +++ "b/leetcode_Python/053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" @@ -1,22 +1,22 @@ -# 方法一:累加判断 -class Solution(object): - def maxSubArray(self, nums): - sum = 0 - max_sum = nums[0] - for num in nums: - sum += num - if sum > max_sum: - max_sum = sum - if sum < 0: - sum = 0 - return max_sum - -# 方法二:动态规划,dp[i]表示以下标i元素结尾的数组最大和 -class Solution(object): - def maxSubArray(self, nums): - n = len(nums) - dp = [nums[0] for _ in range(n)] - for i in range(1, n): - # 前一状态最大和加上当前元素值,与当前元素值比较出较大者 - dp[i] = max(dp[i-1] + nums[i], nums[i]) - return max(dp) +# 方法一:累加判断 +class Solution(object): + def maxSubArray(self, nums): + sum = 0 + max_sum = nums[0] + for num in nums: + sum += num + if sum > max_sum: + max_sum = sum + if sum < 0: + sum = 0 + return max_sum + +# 方法二:动态规划,dp[i]表示以下标i元素结尾的数组最大和 +class Solution(object): + def maxSubArray(self, nums): + n = len(nums) + dp = [nums[0] for _ in range(n)] + for i in range(1, n): + # 前一状态最大和加上当前元素值,与当前元素值比较出较大者 + dp[i] = max(dp[i-1] + nums[i], nums[i]) + return max(dp) diff --git "a/leetcode/055.\350\267\263\350\267\203\346\270\270\346\210\217.py" "b/leetcode_Python/055.\350\267\263\350\267\203\346\270\270\346\210\217.py" similarity index 97% rename from "leetcode/055.\350\267\263\350\267\203\346\270\270\346\210\217.py" rename to "leetcode_Python/055.\350\267\263\350\267\203\346\270\270\346\210\217.py" index 5f3ed8f..3176e9e 100644 --- "a/leetcode/055.\350\267\263\350\267\203\346\270\270\346\210\217.py" +++ "b/leetcode_Python/055.\350\267\263\350\267\203\346\270\270\346\210\217.py" @@ -1,9 +1,9 @@ -# 若数组i位置加上可跳跃步数大于终点位置,且i位置可到达,则能够到达终点 -class Solution(object): - def canJump(self, nums): - max_step = 0 - for i in range(len(nums)): - if i > max_step: - return False - max_step = max(nums[i]+i, max_step) +# 若数组i位置加上可跳跃步数大于终点位置,且i位置可到达,则能够到达终点 +class Solution(object): + def canJump(self, nums): + max_step = 0 + for i in range(len(nums)): + if i > max_step: + return False + max_step = max(nums[i]+i, max_step) return True \ No newline at end of file diff --git "a/leetcode/058.\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" "b/leetcode_Python/058.\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" similarity index 97% rename from "leetcode/058.\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" rename to "leetcode_Python/058.\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" index caba7a3..3e9ad8c 100644 --- "a/leetcode/058.\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" +++ "b/leetcode_Python/058.\346\234\200\345\220\216\344\270\200\344\270\252\345\215\225\350\257\215\347\232\204\351\225\277\345\272\246.py" @@ -1,4 +1,4 @@ -class Solution(object): - def lengthOfLastWord(self, s): - s = s.split() +class Solution(object): + def lengthOfLastWord(self, s): + s = s.split() return len(s[-1]) if s else 0 \ No newline at end of file diff --git "a/leetcode/060.\347\254\254k\344\270\252\346\216\222\345\210\227.py" "b/leetcode_Python/060.\347\254\254k\344\270\252\346\216\222\345\210\227.py" similarity index 96% rename from "leetcode/060.\347\254\254k\344\270\252\346\216\222\345\210\227.py" rename to "leetcode_Python/060.\347\254\254k\344\270\252\346\216\222\345\210\227.py" index daa7cff..551a128 100644 --- "a/leetcode/060.\347\254\254k\344\270\252\346\216\222\345\210\227.py" +++ "b/leetcode_Python/060.\347\254\254k\344\270\252\346\216\222\345\210\227.py" @@ -1,39 +1,39 @@ -# 回溯法,先算出全部全排列,再取第k个 -class Solution(object): - def getPermutation(self, n, k): - def gen(output, nums): - if not nums: - res.append(output) - for i in range(len(nums)): - gen(output + str(nums[i]), nums[:i] + nums[i+1:]) - - res = [] - nums = [i for i in range(1, n+1)] - gen('', nums) - return res[k-1] - - -# 找规律,一位一位地组合数字 -import math -class Solution(object): - def getPermutation(self, n, k): - nums = [str(i) for i in range(1, n+1)] - res = '' - n -= 1 - while n >= 0: - # n个数,以每一位数字开头有(n-1)!个排列 - fac_n = math.factorial(n) - - # 确定n个数中第k个排列的第一位数的位置,向上取整再减1,该行等于以下四行 - loc = math.ceil(k / fac_n) - 1 - # if k % fac_n: - # loc = k // fac_n - # else: - # loc = k // fac_n - 1 - - res += nums[loc] - nums.pop(loc) - # 确定了前一位数后,k减去前面已排除的多个(n-1)!全排列 - k %= fac_n - n -= 1 +# 回溯法,先算出全部全排列,再取第k个 +class Solution(object): + def getPermutation(self, n, k): + def gen(output, nums): + if not nums: + res.append(output) + for i in range(len(nums)): + gen(output + str(nums[i]), nums[:i] + nums[i+1:]) + + res = [] + nums = [i for i in range(1, n+1)] + gen('', nums) + return res[k-1] + + +# 找规律,一位一位地组合数字 +import math +class Solution(object): + def getPermutation(self, n, k): + nums = [str(i) for i in range(1, n+1)] + res = '' + n -= 1 + while n >= 0: + # n个数,以每一位数字开头有(n-1)!个排列 + fac_n = math.factorial(n) + + # 确定n个数中第k个排列的第一位数的位置,向上取整再减1,该行等于以下四行 + loc = math.ceil(k / fac_n) - 1 + # if k % fac_n: + # loc = k // fac_n + # else: + # loc = k // fac_n - 1 + + res += nums[loc] + nums.pop(loc) + # 确定了前一位数后,k减去前面已排除的多个(n-1)!全排列 + k %= fac_n + n -= 1 return res \ No newline at end of file diff --git "a/leetcode/061.\346\227\213\350\275\254\351\223\276\350\241\250.py" "b/leetcode_Python/061.\346\227\213\350\275\254\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/061.\346\227\213\350\275\254\351\223\276\350\241\250.py" rename to "leetcode_Python/061.\346\227\213\350\275\254\351\223\276\350\241\250.py" index 9784ffc..b14f5d5 100644 --- "a/leetcode/061.\346\227\213\350\275\254\351\223\276\350\241\250.py" +++ "b/leetcode_Python/061.\346\227\213\350\275\254\351\223\276\350\241\250.py" @@ -1,37 +1,37 @@ -# 方法一:将倒数k个结点移到前面。使用数组存放结点值,位置移动后再转为链表 -class Solution(object): - def rotateRight(self, head, k): - if not head: - return - res = [] - while head: - res.append(head.val) - head = head.next - K = k%len(res) - res = res[-K:] + res[:-K] - head = h = ListNode(None) - for i in res: - head.next = ListNode(i) - head = head.next - return h.next - -# 方法二:将链表首尾连接成环,再根据要求确定新的头结点,断开环 -class Solution(object): - def rotateRight(self, head, k): - if not head or not head.next: - return head - - h = head - length = 1 - while h.next: - length += 1 - h = h.next - - h.next = head - step = length - k%length - - for _ in range(step): - h = h.next - res = h.next - h.next = None +# 方法一:将倒数k个结点移到前面。使用数组存放结点值,位置移动后再转为链表 +class Solution(object): + def rotateRight(self, head, k): + if not head: + return + res = [] + while head: + res.append(head.val) + head = head.next + K = k%len(res) + res = res[-K:] + res[:-K] + head = h = ListNode(None) + for i in res: + head.next = ListNode(i) + head = head.next + return h.next + +# 方法二:将链表首尾连接成环,再根据要求确定新的头结点,断开环 +class Solution(object): + def rotateRight(self, head, k): + if not head or not head.next: + return head + + h = head + length = 1 + while h.next: + length += 1 + h = h.next + + h.next = head + step = length - k%length + + for _ in range(step): + h = h.next + res = h.next + h.next = None return res \ No newline at end of file diff --git "a/leetcode/064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" "b/leetcode_Python/064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" similarity index 97% rename from "leetcode/064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" rename to "leetcode_Python/064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" index e1344f0..89487ea 100644 --- "a/leetcode/064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" +++ "b/leetcode_Python/064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" @@ -1,52 +1,52 @@ -# 动态规划,dp记录每个位置的最短路径 -# 状态转移方程 dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] -class Solution(object): - def minPathSum(self, grid): - m, n = len(grid), len(grid[0]) - dp = [[0]*n]*m - for i in range(m): - for j in range(n): - if i == 0 and j == 0: - dp[i][j] = grid[i][j] - elif i == 0 and j != 0: - dp[i][j] = dp[i][j-1] + grid[i][j] - elif i != 0 and j == 0: - dp[i][j] = dp[i-1][j] + grid[i][j] - else: - dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] - return dp[-1][-1] - - -# 原地修改 -class Solution2(object): - def minPathSum(self, grid): - for i in range(len(grid)): - for j in range(len(grid[0])): - if i == 0 and j == 0: - continue - elif i == 0 and j != 0: - grid[i][j] += grid[i][j-1] - elif i != 0 and j == 0: - grid[i][j] += grid[i-1][j] - else: - grid[i][j] += min(grid[i-1][j], grid[i][j-1]) - return grid[-1][-1] - - -# 动态规划经典写法 -class Solution(object): - def minPathSum(self, grid): - m, n = len(grid), len(grid[0]) - dp = [[0]*n for _ in range(m)] - dp[0][0] = grid[0][0] - # 初始化首行首列 - for i in range(1, m): - dp[i][0] = dp[i-1][0] + grid[i][0] - for j in range(1, n): - dp[0][j] = dp[0][j-1] + grid[0][j] - # 遍历每个位置 - for i in range(1, m): - for j in range(1, n): - dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] - - return dp[-1][-1] +# 动态规划,dp记录每个位置的最短路径 +# 状态转移方程 dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] +class Solution(object): + def minPathSum(self, grid): + m, n = len(grid), len(grid[0]) + dp = [[0]*n]*m + for i in range(m): + for j in range(n): + if i == 0 and j == 0: + dp[i][j] = grid[i][j] + elif i == 0 and j != 0: + dp[i][j] = dp[i][j-1] + grid[i][j] + elif i != 0 and j == 0: + dp[i][j] = dp[i-1][j] + grid[i][j] + else: + dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] + return dp[-1][-1] + + +# 原地修改 +class Solution2(object): + def minPathSum(self, grid): + for i in range(len(grid)): + for j in range(len(grid[0])): + if i == 0 and j == 0: + continue + elif i == 0 and j != 0: + grid[i][j] += grid[i][j-1] + elif i != 0 and j == 0: + grid[i][j] += grid[i-1][j] + else: + grid[i][j] += min(grid[i-1][j], grid[i][j-1]) + return grid[-1][-1] + + +# 动态规划经典写法 +class Solution(object): + def minPathSum(self, grid): + m, n = len(grid), len(grid[0]) + dp = [[0]*n for _ in range(m)] + dp[0][0] = grid[0][0] + # 初始化首行首列 + for i in range(1, m): + dp[i][0] = dp[i-1][0] + grid[i][0] + for j in range(1, n): + dp[0][j] = dp[0][j-1] + grid[0][j] + # 遍历每个位置 + for i in range(1, m): + for j in range(1, n): + dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] + + return dp[-1][-1] diff --git "a/leetcode/066.\345\212\2401.py" "b/leetcode_Python/066.\345\212\2401.py" similarity index 97% rename from "leetcode/066.\345\212\2401.py" rename to "leetcode_Python/066.\345\212\2401.py" index f4c5b75..95cd703 100644 --- "a/leetcode/066.\345\212\2401.py" +++ "b/leetcode_Python/066.\345\212\2401.py" @@ -1,8 +1,8 @@ -# 整型列表转化为数字,加1后再转化为整型列表 -class Solution(object): - def plusOne(self, digits): - num = int(''.join(str(i) for i in digits)) + 1 - new_digits = [] - for i in str(num): - new_digits.append(int(i)) +# 整型列表转化为数字,加1后再转化为整型列表 +class Solution(object): + def plusOne(self, digits): + num = int(''.join(str(i) for i in digits)) + 1 + new_digits = [] + for i in str(num): + new_digits.append(int(i)) return new_digits \ No newline at end of file diff --git "a/leetcode/067.\344\272\214\350\277\233\345\210\266\346\261\202\345\222\214.py" "b/leetcode_Python/067.\344\272\214\350\277\233\345\210\266\346\261\202\345\222\214.py" similarity index 98% rename from "leetcode/067.\344\272\214\350\277\233\345\210\266\346\261\202\345\222\214.py" rename to "leetcode_Python/067.\344\272\214\350\277\233\345\210\266\346\261\202\345\222\214.py" index 3fdf9f2..00f1a89 100644 --- "a/leetcode/067.\344\272\214\350\277\233\345\210\266\346\261\202\345\222\214.py" +++ "b/leetcode_Python/067.\344\272\214\350\277\233\345\210\266\346\261\202\345\222\214.py" @@ -1,4 +1,4 @@ -# 转化为十进制求和,再将结果转为二进制,要去除开头的‘0b’ -class Solution(object): - def addBinary(self, a, b): +# 转化为十进制求和,再将结果转为二进制,要去除开头的‘0b’ +class Solution(object): + def addBinary(self, a, b): return bin(int(a, 2) + int(b, 2))[2:] \ No newline at end of file diff --git "a/leetcode/069.x \347\232\204\345\271\263\346\226\271\346\240\271.py" "b/leetcode_Python/069.x \347\232\204\345\271\263\346\226\271\346\240\271.py" similarity index 96% rename from "leetcode/069.x \347\232\204\345\271\263\346\226\271\346\240\271.py" rename to "leetcode_Python/069.x \347\232\204\345\271\263\346\226\271\346\240\271.py" index 669e8fa..f05ea9f 100644 --- "a/leetcode/069.x \347\232\204\345\271\263\346\226\271\346\240\271.py" +++ "b/leetcode_Python/069.x \347\232\204\345\271\263\346\226\271\346\240\271.py" @@ -1,9 +1,9 @@ -# 方法一:数学函数 -class Solution(object): - def mySqrt(self, x): - return int(math.sqrt(x)) - -# 方法二:1/2次方取整 -class Solution(object): - def mySqrt(self, x): +# 方法一:数学函数 +class Solution(object): + def mySqrt(self, x): + return int(math.sqrt(x)) + +# 方法二:1/2次方取整 +class Solution(object): + def mySqrt(self, x): return int(x**(1/2.0)) \ No newline at end of file diff --git "a/leetcode/070.\347\210\254\346\245\274\346\242\257.py" "b/leetcode_Python/070.\347\210\254\346\245\274\346\242\257.py" similarity index 96% rename from "leetcode/070.\347\210\254\346\245\274\346\242\257.py" rename to "leetcode_Python/070.\347\210\254\346\245\274\346\242\257.py" index f144fe4..cd084be 100644 --- "a/leetcode/070.\347\210\254\346\245\274\346\242\257.py" +++ "b/leetcode_Python/070.\347\210\254\346\245\274\346\242\257.py" @@ -1,26 +1,26 @@ -# 规律:1,2,3,5,8 -# 方法一:递推 -class Solution(object): - def climbStairs(self, n): - if n<3: - return n - a, b = 1, 2 - while n>2: - a, b = b, a+b - n -= 1 - return b - -# 方法二:递归 -class Solution(object): - def climbStairs(self, n): - if n in [1, 2]: - return n - return self.climbStairs(n-1) + self.climbStairs(n-2) - -# 方法三:动态规划 -class Solution(object): - def climbStairs(self, n): - res = [1] * (n+1) - for i in range(2, n+1): - res[i] = res[i-1] + res[i-2] +# 规律:1,2,3,5,8 +# 方法一:递推 +class Solution(object): + def climbStairs(self, n): + if n<3: + return n + a, b = 1, 2 + while n>2: + a, b = b, a+b + n -= 1 + return b + +# 方法二:递归 +class Solution(object): + def climbStairs(self, n): + if n in [1, 2]: + return n + return self.climbStairs(n-1) + self.climbStairs(n-2) + +# 方法三:动态规划 +class Solution(object): + def climbStairs(self, n): + res = [1] * (n+1) + for i in range(2, n+1): + res[i] = res[i-1] + res[i-2] return res[-1] \ No newline at end of file diff --git "a/leetcode/072.\347\274\226\350\276\221\350\267\235\347\246\273.py" "b/leetcode_Python/072.\347\274\226\350\276\221\350\267\235\347\246\273.py" similarity index 97% rename from "leetcode/072.\347\274\226\350\276\221\350\267\235\347\246\273.py" rename to "leetcode_Python/072.\347\274\226\350\276\221\350\267\235\347\246\273.py" index 9c819c3..7d1bbb5 100644 --- "a/leetcode/072.\347\274\226\350\276\221\350\267\235\347\246\273.py" +++ "b/leetcode_Python/072.\347\274\226\350\276\221\350\267\235\347\246\273.py" @@ -1,30 +1,30 @@ -# dp[i][j] 表示 word1[:i] 和 word2[:j] 的编辑距离 -class Solution(object): - def minDistance(self, word1, word2): - m, n = len(word1), len(word2) - dp = [[0]*(n+1) for _ in range(m+1)] - # 初始化数组 - for i in range(1, n+1): - dp[0][i] = i - for j in range(1, m+1): - dp[j][0] = j - for i in range(1, m+1): - for j in range(1, n+1): - if word1[i-1] == word2[j-1]: - # 两字符相等,则当前状态等于前一状态 - dp[i][j] = dp[i-1][j-1] - else: - # 添加:dp[i][j-1]表面上是删除word2最后一个字符,换个角度理解是在word1添加word2的最后一个字符,两者相等抵消 - # 删除:dp[i-1][j]相当于删除word1最后一个字符 - # 替换:dp[i-1][j-1]相当于替换word1最后一个字符为word2最后一个字符 - # 取三种操作中之前状态的最小操作数,每次操作后操作数需加1 - dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) - return dp[-1][-1] - -# r o s -# 0 1 2 3 -# h 1 1 2 3 -# o 2 2 1 2 -# r 3 2 2 2 -# s 4 3 3 2 +# dp[i][j] 表示 word1[:i] 和 word2[:j] 的编辑距离 +class Solution(object): + def minDistance(self, word1, word2): + m, n = len(word1), len(word2) + dp = [[0]*(n+1) for _ in range(m+1)] + # 初始化数组 + for i in range(1, n+1): + dp[0][i] = i + for j in range(1, m+1): + dp[j][0] = j + for i in range(1, m+1): + for j in range(1, n+1): + if word1[i-1] == word2[j-1]: + # 两字符相等,则当前状态等于前一状态 + dp[i][j] = dp[i-1][j-1] + else: + # 添加:dp[i][j-1]表面上是删除word2最后一个字符,换个角度理解是在word1添加word2的最后一个字符,两者相等抵消 + # 删除:dp[i-1][j]相当于删除word1最后一个字符 + # 替换:dp[i-1][j-1]相当于替换word1最后一个字符为word2最后一个字符 + # 取三种操作中之前状态的最小操作数,每次操作后操作数需加1 + dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + return dp[-1][-1] + +# r o s +# 0 1 2 3 +# h 1 1 2 3 +# o 2 2 1 2 +# r 3 2 2 2 +# s 4 3 3 2 # e 5 4 4 3 \ No newline at end of file diff --git "a/leetcode/077.\347\273\204\345\220\210.py" "b/leetcode_Python/077.\347\273\204\345\220\210.py" similarity index 97% rename from "leetcode/077.\347\273\204\345\220\210.py" rename to "leetcode_Python/077.\347\273\204\345\220\210.py" index 8c00a82..4746d08 100644 --- "a/leetcode/077.\347\273\204\345\220\210.py" +++ "b/leetcode_Python/077.\347\273\204\345\220\210.py" @@ -1,20 +1,20 @@ -class Solution(object): - def combine(self, n, k): - # 参数:数值,输出数组 - def dfs(num, output): - # 终止条件,将满足条件的结果添加到全局数组,返回空结束当前递归 - if len(output) == k: - res.append(output) - return - # 剪枝条件 - elif num > n: - return - # 数值和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - dfs(num + 1, output + [num]) - dfs(num + 1, output) - - # 全局数组,存放所有结果 - res = [] - # 调用递归,设置初值 - dfs(1, []) +class Solution(object): + def combine(self, n, k): + # 参数:数值,输出数组 + def dfs(num, output): + # 终止条件,将满足条件的结果添加到全局数组,返回空结束当前递归 + if len(output) == k: + res.append(output) + return + # 剪枝条件 + elif num > n: + return + # 数值和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + dfs(num + 1, output + [num]) + dfs(num + 1, output) + + # 全局数组,存放所有结果 + res = [] + # 调用递归,设置初值 + dfs(1, []) return res \ No newline at end of file diff --git "a/leetcode/078.\345\255\220\351\233\206.py" "b/leetcode_Python/078.\345\255\220\351\233\206.py" similarity index 96% rename from "leetcode/078.\345\255\220\351\233\206.py" rename to "leetcode_Python/078.\345\255\220\351\233\206.py" index 3a03fc3..627c8aa 100644 --- "a/leetcode/078.\345\255\220\351\233\206.py" +++ "b/leetcode_Python/078.\345\255\220\351\233\206.py" @@ -1,69 +1,69 @@ -# 递归 -class Solution(object): - def subsets(self, nums): - # 终止条件,返回空集 - if not nums: - return [[]] - # 获取剩余数组的子集 - sub = self.subsets(nums[1:]) - # 将第一个元素添加到所有子集中构成新的子集 - return [([nums[0]] + s) for s in sub] + sub - - -# 迭代 -class Solution2(object): - def subsets(self, nums): - # 初始化结果数组 - res = [[]] - for num in nums: - # 每次迭代将新的数添加到已有子集中构成新的子集 - res += [v+[num] for v in res] - return res - - -# 回溯 -class Solution3(object): - def subsets(self, nums): - - def find(nums, index, output): - # 每一个新的数组都是子集,可直接添加到全局数组 - res.append(output) - # 遍历数组 - for i in range(index, len(nums)): - # 通过索引控制可取数组元素 - find(nums, i + 1, output + [nums[i]]) - - res = [] - find(nums, 0, []) - return res - - -# 回溯 -class Solution4(object): - def subsets(self, nums): - - def find(nums, index, output, res): - res.append(output) - for i in range(index, len(nums)): - # 先更新输出数组,递归回溯后再弹出新值,还原输出数组,搜索下一种情况 - output.append(nums[i]) - find(nums, i + 1, output, res) - output.pop() - - res = [] - find(nums, 0, [], res) - return res - - -# 回溯 -class Solution5(object): - def subsets(self, nums): - def find(nums, output): - res.append(output) - for i in range(len(nums)): - # 数值数组和输出数组元素动态更新 - find(nums[i+1:], output + [nums[i]]) - - res = [] - find(nums, []) +# 递归 +class Solution(object): + def subsets(self, nums): + # 终止条件,返回空集 + if not nums: + return [[]] + # 获取剩余数组的子集 + sub = self.subsets(nums[1:]) + # 将第一个元素添加到所有子集中构成新的子集 + return [([nums[0]] + s) for s in sub] + sub + + +# 迭代 +class Solution2(object): + def subsets(self, nums): + # 初始化结果数组 + res = [[]] + for num in nums: + # 每次迭代将新的数添加到已有子集中构成新的子集 + res += [v+[num] for v in res] + return res + + +# 回溯 +class Solution3(object): + def subsets(self, nums): + + def find(nums, index, output): + # 每一个新的数组都是子集,可直接添加到全局数组 + res.append(output) + # 遍历数组 + for i in range(index, len(nums)): + # 通过索引控制可取数组元素 + find(nums, i + 1, output + [nums[i]]) + + res = [] + find(nums, 0, []) + return res + + +# 回溯 +class Solution4(object): + def subsets(self, nums): + + def find(nums, index, output, res): + res.append(output) + for i in range(index, len(nums)): + # 先更新输出数组,递归回溯后再弹出新值,还原输出数组,搜索下一种情况 + output.append(nums[i]) + find(nums, i + 1, output, res) + output.pop() + + res = [] + find(nums, 0, [], res) + return res + + +# 回溯 +class Solution5(object): + def subsets(self, nums): + def find(nums, output): + res.append(output) + for i in range(len(nums)): + # 数值数组和输出数组元素动态更新 + find(nums[i+1:], output + [nums[i]]) + + res = [] + find(nums, []) return res \ No newline at end of file diff --git "a/leetcode/079.\345\215\225\350\257\215\346\220\234\347\264\242.py" "b/leetcode_Python/079.\345\215\225\350\257\215\346\220\234\347\264\242.py" similarity index 97% rename from "leetcode/079.\345\215\225\350\257\215\346\220\234\347\264\242.py" rename to "leetcode_Python/079.\345\215\225\350\257\215\346\220\234\347\264\242.py" index d1210c2..526e288 100644 --- "a/leetcode/079.\345\215\225\350\257\215\346\220\234\347\264\242.py" +++ "b/leetcode_Python/079.\345\215\225\350\257\215\346\220\234\347\264\242.py" @@ -1,29 +1,29 @@ -class Solution(object): - def exist(self, board, word): - m, n = len(board), len(board[0]) - d = [(0, 1), (0, -1), (1, 0), (-1, 0)] - - def dfs(x, y, word, board): - # 递归终止条件,全部搜索完成 - if not word: - return True - # 记录字符,然后变换该字符,避免重用 - c = board[x][y] - board[x][y] = '.' - # 遍历搜索四个方向的字符 - for dx, dy in d: - nx, ny = x+dx, y+dy - if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == word[0] and dfs(nx, ny, word[1:], board): - return True - # 四个方向都不满足条件,回溯,返回False - board[x][y] = c - return False - - # 遍历二维矩阵每个字符,深度优先搜索 - for i in range(m): - for j in range(n): - # 有一条路径满足条件 - if board[i][j] == word[0] and dfs(i, j, word[1:], board): - return True - # 全部不满足条件 +class Solution(object): + def exist(self, board, word): + m, n = len(board), len(board[0]) + d = [(0, 1), (0, -1), (1, 0), (-1, 0)] + + def dfs(x, y, word, board): + # 递归终止条件,全部搜索完成 + if not word: + return True + # 记录字符,然后变换该字符,避免重用 + c = board[x][y] + board[x][y] = '.' + # 遍历搜索四个方向的字符 + for dx, dy in d: + nx, ny = x+dx, y+dy + if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == word[0] and dfs(nx, ny, word[1:], board): + return True + # 四个方向都不满足条件,回溯,返回False + board[x][y] = c + return False + + # 遍历二维矩阵每个字符,深度优先搜索 + for i in range(m): + for j in range(n): + # 有一条路径满足条件 + if board[i][j] == word[0] and dfs(i, j, word[1:], board): + return True + # 全部不满足条件 return False \ No newline at end of file diff --git "a/leetcode/082.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240II.py" "b/leetcode_Python/082.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240II.py" similarity index 97% rename from "leetcode/082.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240II.py" rename to "leetcode_Python/082.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240II.py" index 710bd25..743e9c2 100644 --- "a/leetcode/082.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240II.py" +++ "b/leetcode_Python/082.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240II.py" @@ -1,53 +1,53 @@ -# 方法一:数组去重再连接成链表 -class Solution(object): - def deleteDuplicates(self, head): - if not head: - return - # 将链表结点值存放在数组 - res = [] - while head: - res.append(head.val) - head = head.next - # 去除重复的元素 - res2 = [] - for i in res: - if res.count(i) == 1: - res2.append(i) - # 将数组元素连接成链表 - h = head = ListNode(0) - for i in res2: - head.next = ListNode(i) - head = head.next - return h.next - -# 方法二:pre跟踪head的前一个结点进行判断,cur跟踪新链表的尾结点 -class Solution(object): - def deleteDuplicates(self, head): - # 创建起始结点,不影响原链表 - res = pre = cur = ListNode(None) - # 遍历链表结点 - while head: - # 结点值与左或右相同时,说明重复,指针向前移动。求结点的值时要先判断结点是否存在 - while head and ((head.val==pre.val) or (head.next and head.val==head.next.val)): - pre = head - head = head.next - # 不重复时连接到新链表 - cur.next = head - cur = cur.next - # 尾结点可能为重复结点,需要先判断head是否为空,再继续遍历下一个结点 - if head: - head = head.next - return res.next - -# 方法三:递归 -class Solution(object): - # 方法的作用是:参数给一个跟前面结点不重复的head,再判断跟后面结点是否重复, - # 不重复则返回head,重复则返回head.next,head.next可能有不重复结点也可能为空 - def deleteDuplicates(self, head): - if not head: - return None - lat, dup = head.next, False - while lat and lat.val == head.val: - lat, dup = lat.next, True - head.next = self.deleteDuplicates(lat) +# 方法一:数组去重再连接成链表 +class Solution(object): + def deleteDuplicates(self, head): + if not head: + return + # 将链表结点值存放在数组 + res = [] + while head: + res.append(head.val) + head = head.next + # 去除重复的元素 + res2 = [] + for i in res: + if res.count(i) == 1: + res2.append(i) + # 将数组元素连接成链表 + h = head = ListNode(0) + for i in res2: + head.next = ListNode(i) + head = head.next + return h.next + +# 方法二:pre跟踪head的前一个结点进行判断,cur跟踪新链表的尾结点 +class Solution(object): + def deleteDuplicates(self, head): + # 创建起始结点,不影响原链表 + res = pre = cur = ListNode(None) + # 遍历链表结点 + while head: + # 结点值与左或右相同时,说明重复,指针向前移动。求结点的值时要先判断结点是否存在 + while head and ((head.val==pre.val) or (head.next and head.val==head.next.val)): + pre = head + head = head.next + # 不重复时连接到新链表 + cur.next = head + cur = cur.next + # 尾结点可能为重复结点,需要先判断head是否为空,再继续遍历下一个结点 + if head: + head = head.next + return res.next + +# 方法三:递归 +class Solution(object): + # 方法的作用是:参数给一个跟前面结点不重复的head,再判断跟后面结点是否重复, + # 不重复则返回head,重复则返回head.next,head.next可能有不重复结点也可能为空 + def deleteDuplicates(self, head): + if not head: + return None + lat, dup = head.next, False + while lat and lat.val == head.val: + lat, dup = lat.next, True + head.next = self.deleteDuplicates(lat) return head.next if dup else head \ No newline at end of file diff --git "a/leetcode/083.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" "b/leetcode_Python/083.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" similarity index 97% rename from "leetcode/083.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" rename to "leetcode_Python/083.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" index 243a97e..2a95966 100644 --- "a/leetcode/083.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" +++ "b/leetcode_Python/083.\345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240.py" @@ -1,9 +1,9 @@ -# 值相同则将next指针指向下下位,重复判断每个结点 -class Solution(object): - def deleteDuplicates(self, head): - res = head - while head: - while head.next and head.val == head.next.val: - head.next = head.next.next - head = head.next +# 值相同则将next指针指向下下位,重复判断每个结点 +class Solution(object): + def deleteDuplicates(self, head): + res = head + while head: + while head.next and head.val == head.next.val: + head.next = head.next.next + head = head.next return res \ No newline at end of file diff --git "a/leetcode/086.\345\210\206\351\232\224\351\223\276\350\241\250.py" "b/leetcode_Python/086.\345\210\206\351\232\224\351\223\276\350\241\250.py" similarity index 97% rename from "leetcode/086.\345\210\206\351\232\224\351\223\276\350\241\250.py" rename to "leetcode_Python/086.\345\210\206\351\232\224\351\223\276\350\241\250.py" index 122fdd7..4bba67d 100644 --- "a/leetcode/086.\345\210\206\351\232\224\351\223\276\350\241\250.py" +++ "b/leetcode_Python/086.\345\210\206\351\232\224\351\223\276\350\241\250.py" @@ -1,17 +1,17 @@ -# 将=x的结点分别组成新链表,再将两个链表连接 -class Solution(object): - def partition(self, head, x): - h1 = head1 = ListNode(0) - h2 = head2 = ListNode(0) - while head: - if head.val < x: - h1.next = head - h1 = h1.next - else: - h2.next = head - h2 = h2.next - head = head.next - # 由于尾结点可能还连接着=x的结点分别组成新链表,再将两个链表连接 +class Solution(object): + def partition(self, head, x): + h1 = head1 = ListNode(0) + h2 = head2 = ListNode(0) + while head: + if head.val < x: + h1.next = head + h1 = h1.next + else: + h2.next = head + h2 = h2.next + head = head.next + # 由于尾结点可能还连接着 end: - return [None] - res = [] - for i in range(start, end+1): - lefts = self.constructTrees(start, i-1) - rights = self.constructTrees(i+1, end) - for left in lefts: - for right in rights: - root = TreeNode(i) - root.left = left - root.right = right - res.append(root) - return res - -################# 递归思路 ################# -# 方法作用极简化:先判断一个结点的情况 -# 方法作用描述:将给定起止范围的值转为结点添加到数组中,并返回该数组 -def constructTrees(self, start, end): - # 没有合适的范围,返回空结点 - if start > end: - return [None] - res = [] - for i in range(start, end+1): - root = TreeNode(i) - res.append(root) +class Solution(object): + def generateTrees(self, n): + if n == 0: + return [] + return self.constructTrees(1, n) + + def constructTrees(self, start, end): + if start > end: + return [None] + res = [] + for i in range(start, end+1): + lefts = self.constructTrees(start, i-1) + rights = self.constructTrees(i+1, end) + for left in lefts: + for right in rights: + root = TreeNode(i) + root.left = left + root.right = right + res.append(root) + return res + +################# 递归思路 ################# +# 方法作用极简化:先判断一个结点的情况 +# 方法作用描述:将给定起止范围的值转为结点添加到数组中,并返回该数组 +def constructTrees(self, start, end): + # 没有合适的范围,返回空结点 + if start > end: + return [None] + res = [] + for i in range(start, end+1): + root = TreeNode(i) + res.append(root) return res \ No newline at end of file diff --git "a/leetcode/096.\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/096.\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 98% rename from "leetcode/096.\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/096.\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index f7be30d..8cb8b54 100644 --- "a/leetcode/096.\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/096.\344\270\215\345\220\214\347\232\204\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,11 +1,11 @@ -# 动态规划:1到n都可以作为二叉搜索树的根节点,当k是根节点时,它的左边有k-1个不等的数,它的右边有n-k个不等的数 -# 以k为根节点的二叉搜索树的种类就是左右可能的种类的乘积 -class Solution(object): - def numTrees(self, n): - dp = [1 for i in range(n+1)] - for i in range(2, n+1): - s = 0 - for k in range(i): - s += dp[k] * dp[i-k-1] - dp[i] = s +# 动态规划:1到n都可以作为二叉搜索树的根节点,当k是根节点时,它的左边有k-1个不等的数,它的右边有n-k个不等的数 +# 以k为根节点的二叉搜索树的种类就是左右可能的种类的乘积 +class Solution(object): + def numTrees(self, n): + dp = [1 for i in range(n+1)] + for i in range(2, n+1): + s = 0 + for k in range(i): + s += dp[k] * dp[i-k-1] + dp[i] = s return dp[-1] \ No newline at end of file diff --git "a/leetcode/098.\351\252\214\350\257\201\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/098.\351\252\214\350\257\201\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 96% rename from "leetcode/098.\351\252\214\350\257\201\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/098.\351\252\214\350\257\201\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index 8f7445d..3d11fcc 100644 --- "a/leetcode/098.\351\252\214\350\257\201\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/098.\351\252\214\350\257\201\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,16 +1,16 @@ -# 中序遍历,遍历数组看是否递增 -class Solution(object): - def isValidBST(self, root): - global res - res = [] - self.inOrder(root) - for i in range(len(res)-1): - if res[i] >= res[i+1]: - return False - return True - def inOrder(self, root): - if not root: - return - self.inOrder(root.left) - res.append(root.val) +# 中序遍历,遍历数组看是否递增 +class Solution(object): + def isValidBST(self, root): + global res + res = [] + self.inOrder(root) + for i in range(len(res)-1): + if res[i] >= res[i+1]: + return False + return True + def inOrder(self, root): + if not root: + return + self.inOrder(root.left) + res.append(root.val) self.inOrder(root.right) \ No newline at end of file diff --git "a/leetcode/099.\346\201\242\345\244\215\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/099.\346\201\242\345\244\215\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 97% rename from "leetcode/099.\346\201\242\345\244\215\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/099.\346\201\242\345\244\215\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index 46edc85..b5de3b7 100644 --- "a/leetcode/099.\346\201\242\345\244\215\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/099.\346\201\242\345\244\215\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,24 +1,24 @@ -# 1) 被交换的两个结点相邻,如124356,只需要把相邻的3和4交换回来即可; -# 2) 被交换的两个结点不相邻,如163452,需要找出两个逆序的地方,63和52,并交换第一个逆序的前者和第二个逆序的后者。 -class Solution(object): - def __init__(self): - self.mistake1 = None - self.mistake2 = None - self.pre = None - - def recoverTree(self, root): - if not root: - return None - self.findMistake(root) - self.mistake1.val, self.mistake2.val = self.mistake2.val, self.mistake1.val - - def findMistake(self, root): - if root.left: - self.findMistake(root.left) - if self.pre and root.val < self.pre.val: - if not self.mistake1: - self.mistake1 = self.pre - self.mistake2 = root - self.pre = root - if root.right: +# 1) 被交换的两个结点相邻,如124356,只需要把相邻的3和4交换回来即可; +# 2) 被交换的两个结点不相邻,如163452,需要找出两个逆序的地方,63和52,并交换第一个逆序的前者和第二个逆序的后者。 +class Solution(object): + def __init__(self): + self.mistake1 = None + self.mistake2 = None + self.pre = None + + def recoverTree(self, root): + if not root: + return None + self.findMistake(root) + self.mistake1.val, self.mistake2.val = self.mistake2.val, self.mistake1.val + + def findMistake(self, root): + if root.left: + self.findMistake(root.left) + if self.pre and root.val < self.pre.val: + if not self.mistake1: + self.mistake1 = self.pre + self.mistake2 = root + self.pre = root + if root.right: self.findMistake(root.right) \ No newline at end of file diff --git "a/leetcode/100.\347\233\270\345\220\214\347\232\204\346\240\221.py" "b/leetcode_Python/100.\347\233\270\345\220\214\347\232\204\346\240\221.py" similarity index 98% rename from "leetcode/100.\347\233\270\345\220\214\347\232\204\346\240\221.py" rename to "leetcode_Python/100.\347\233\270\345\220\214\347\232\204\346\240\221.py" index c975261..5e06454 100644 --- "a/leetcode/100.\347\233\270\345\220\214\347\232\204\346\240\221.py" +++ "b/leetcode_Python/100.\347\233\270\345\220\214\347\232\204\346\240\221.py" @@ -1,9 +1,9 @@ -# 递归判断两棵树对应位置的结点 -# 方法极简化是判断两个结点是否相同,递归后变成判断两棵树是否相同 -class Solution(object): - def isSameTree(self, p, q): - if not p and not q: - return True - if (p and not q) or (not p and q): - return False +# 递归判断两棵树对应位置的结点 +# 方法极简化是判断两个结点是否相同,递归后变成判断两棵树是否相同 +class Solution(object): + def isSameTree(self, p, q): + if not p and not q: + return True + if (p and not q) or (not p and q): + return False return p.val==q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) \ No newline at end of file diff --git "a/leetcode2/1005.K \346\254\241\345\217\226\345\217\215\345\220\216\346\234\200\345\244\247\345\214\226\347\232\204\346\225\260\347\273\204\345\222\214.py" "b/leetcode_Python/1005.K \346\254\241\345\217\226\345\217\215\345\220\216\346\234\200\345\244\247\345\214\226\347\232\204\346\225\260\347\273\204\345\222\214.py" similarity index 97% rename from "leetcode2/1005.K \346\254\241\345\217\226\345\217\215\345\220\216\346\234\200\345\244\247\345\214\226\347\232\204\346\225\260\347\273\204\345\222\214.py" rename to "leetcode_Python/1005.K \346\254\241\345\217\226\345\217\215\345\220\216\346\234\200\345\244\247\345\214\226\347\232\204\346\225\260\347\273\204\345\222\214.py" index 815f71c..dfe695e 100644 --- "a/leetcode2/1005.K \346\254\241\345\217\226\345\217\215\345\220\216\346\234\200\345\244\247\345\214\226\347\232\204\346\225\260\347\273\204\345\222\214.py" +++ "b/leetcode_Python/1005.K \346\254\241\345\217\226\345\217\215\345\220\216\346\234\200\345\244\247\345\214\226\347\232\204\346\225\260\347\273\204\345\222\214.py" @@ -1,8 +1,8 @@ -# 每次将数组最小值取反替换 -class Solution(object): - def largestSumAfterKNegations(self, A, K): - for _ in range(K): - num = min(A) - i = A.index(num) - A[i] = -num +# 每次将数组最小值取反替换 +class Solution(object): + def largestSumAfterKNegations(self, A, K): + for _ in range(K): + num = min(A) + i = A.index(num) + A[i] = -num return sum(A) \ No newline at end of file diff --git "a/leetcode2/1007.\350\241\214\347\233\270\347\255\211\347\232\204\346\234\200\345\260\221\345\244\232\347\261\263\350\257\272\346\227\213\350\275\254.py" "b/leetcode_Python/1007.\350\241\214\347\233\270\347\255\211\347\232\204\346\234\200\345\260\221\345\244\232\347\261\263\350\257\272\346\227\213\350\275\254.py" similarity index 97% rename from "leetcode2/1007.\350\241\214\347\233\270\347\255\211\347\232\204\346\234\200\345\260\221\345\244\232\347\261\263\350\257\272\346\227\213\350\275\254.py" rename to "leetcode_Python/1007.\350\241\214\347\233\270\347\255\211\347\232\204\346\234\200\345\260\221\345\244\232\347\261\263\350\257\272\346\227\213\350\275\254.py" index c58ec55..52f297e 100644 --- "a/leetcode2/1007.\350\241\214\347\233\270\347\255\211\347\232\204\346\234\200\345\260\221\345\244\232\347\261\263\350\257\272\346\227\213\350\275\254.py" +++ "b/leetcode_Python/1007.\350\241\214\347\233\270\347\255\211\347\232\204\346\234\200\345\260\221\345\244\232\347\261\263\350\257\272\346\227\213\350\275\254.py" @@ -1,21 +1,21 @@ -# 如果最终能整排值相同,那么两排各自的第一个多米诺骨牌至少有一个是目标值 -# 取两排第一个值分别进行判断,检查其他多米诺骨牌是否出现该值,若都出现则求出最小翻转次数 -class Solution(object): - def minDominoRotations(self, A, B): - def check(x, n): - a, b = 0, 0 - for i in range(n): - if A[i] != x and B[i] != x: - return -1 - elif A[i] != x: - a += 1 - elif B[i] != x: - b += 1 - return min(a, b) - - n = len(A) - res = check(A[0], n) - if res != -1: - return res - else: +# 如果最终能整排值相同,那么两排各自的第一个多米诺骨牌至少有一个是目标值 +# 取两排第一个值分别进行判断,检查其他多米诺骨牌是否出现该值,若都出现则求出最小翻转次数 +class Solution(object): + def minDominoRotations(self, A, B): + def check(x, n): + a, b = 0, 0 + for i in range(n): + if A[i] != x and B[i] != x: + return -1 + elif A[i] != x: + a += 1 + elif B[i] != x: + b += 1 + return min(a, b) + + n = len(A) + res = check(A[0], n) + if res != -1: + return res + else: return check(B[0], n) \ No newline at end of file diff --git "a/leetcode2/1008.\345\205\210\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/1008.\345\205\210\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode2/1008.\345\205\210\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/1008.\345\205\210\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" index 8ddc4fe..9f758bb 100644 --- "a/leetcode2/1008.\345\205\210\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/1008.\345\205\210\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" @@ -1,15 +1,15 @@ -# 列表第一个值构造为根结点,比根结点小的值作为左子树,比根结点大的值作为右子树,递归构造结点成二叉树 -class Solution(object): - def bstFromPreorder(self, preorder): - if not preorder: - return None - root = TreeNode(preorder[0]) - left, right = [], [] - for num in preorder[1:]: - if num < preorder[0]: - left.append(num) - else: - right.append(num) - root.left = self.bstFromPreorder(left) - root.right = self.bstFromPreorder(right) +# 列表第一个值构造为根结点,比根结点小的值作为左子树,比根结点大的值作为右子树,递归构造结点成二叉树 +class Solution(object): + def bstFromPreorder(self, preorder): + if not preorder: + return None + root = TreeNode(preorder[0]) + left, right = [], [] + for num in preorder[1:]: + if num < preorder[0]: + left.append(num) + else: + right.append(num) + root.left = self.bstFromPreorder(left) + root.right = self.bstFromPreorder(right) return root \ No newline at end of file diff --git "a/leetcode/101.\345\257\271\347\247\260\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/101.\345\257\271\347\247\260\344\272\214\345\217\211\346\240\221.py" similarity index 96% rename from "leetcode/101.\345\257\271\347\247\260\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/101.\345\257\271\347\247\260\344\272\214\345\217\211\346\240\221.py" index 2cf34e9..8620203 100644 --- "a/leetcode/101.\345\257\271\347\247\260\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/101.\345\257\271\347\247\260\344\272\214\345\217\211\346\240\221.py" @@ -1,39 +1,39 @@ -# 判断左右子树对称的两个结点是否相同 -# 嵌套方法写法 -class Solution(object): - def isSymmetric(self, root): - def isSameTree(p, q): - if not p and not q: - return True - if p and q and p.val==q.val: - l = isSameTree(p.left, q.right) - r = isSameTree(p.right, q.left) - return l and r - else: - return False - if not root: - return True - return isSameTree(root.left, root.right) - -# 单独调用写法 -class Solution: - def isSymmetrical(self, pRoot): - if not pRoot: - return True - return self.isSameTree(pRoot.left, pRoot.right) - - def isSameTree(self, p, q): - if not p and not q: - return True - if p and q and p.val==q.val: - l = self.isSameTree(p.left, q.right) - r = self.isSameTree(p.right, q.left) - return l and r - return False - - # def isSameTree(p, q): - # if not p and not q: - # return True - # if (p and not q) or (not p and q): - # return False +# 判断左右子树对称的两个结点是否相同 +# 嵌套方法写法 +class Solution(object): + def isSymmetric(self, root): + def isSameTree(p, q): + if not p and not q: + return True + if p and q and p.val==q.val: + l = isSameTree(p.left, q.right) + r = isSameTree(p.right, q.left) + return l and r + else: + return False + if not root: + return True + return isSameTree(root.left, root.right) + +# 单独调用写法 +class Solution: + def isSymmetrical(self, pRoot): + if not pRoot: + return True + return self.isSameTree(pRoot.left, pRoot.right) + + def isSameTree(self, p, q): + if not p and not q: + return True + if p and q and p.val==q.val: + l = self.isSameTree(p.left, q.right) + r = self.isSameTree(p.right, q.left) + return l and r + return False + + # def isSameTree(p, q): + # if not p and not q: + # return True + # if (p and not q) or (not p and q): + # return False # return p.val == q.val and isSameTree(p.left, q.right) and isSameTree(p.right, q.left) \ No newline at end of file diff --git "a/leetcode/102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" "b/leetcode_Python/102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" similarity index 97% rename from "leetcode/102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" rename to "leetcode_Python/102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" index fb180d2..203d588 100644 --- "a/leetcode/102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" +++ "b/leetcode_Python/102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" @@ -1,21 +1,21 @@ -# cur_list:存放当前行结点 -# next_list:存放下一行结点 -# level:存放当前行的值 -# res:存放所有行的值 -class Solution(object): - def levelOrder(self, root): - res, cur_list, next_list, level = [], [], [], [] - if root: - cur_list = [root] - while cur_list: - while cur_list: - temp = cur_list.pop(0) - level.append(temp.val) - if temp.left: - next_list.append(temp.left) - if temp.right: - next_list.append(temp.right) - res.append(level) - cur_list, next_list, level = next_list, [], [] - return res - +# cur_list:存放当前行结点 +# next_list:存放下一行结点 +# level:存放当前行的值 +# res:存放所有行的值 +class Solution(object): + def levelOrder(self, root): + res, cur_list, next_list, level = [], [], [], [] + if root: + cur_list = [root] + while cur_list: + while cur_list: + temp = cur_list.pop(0) + level.append(temp.val) + if temp.left: + next_list.append(temp.left) + if temp.right: + next_list.append(temp.right) + res.append(level) + cur_list, next_list, level = next_list, [], [] + return res + diff --git "a/leetcode2/1020.\351\243\236\345\234\260\347\232\204\346\225\260\351\207\217.py" "b/leetcode_Python/1020.\351\243\236\345\234\260\347\232\204\346\225\260\351\207\217.py" similarity index 97% rename from "leetcode2/1020.\351\243\236\345\234\260\347\232\204\346\225\260\351\207\217.py" rename to "leetcode_Python/1020.\351\243\236\345\234\260\347\232\204\346\225\260\351\207\217.py" index 58f7bd8..226938a 100644 --- "a/leetcode2/1020.\351\243\236\345\234\260\347\232\204\346\225\260\351\207\217.py" +++ "b/leetcode_Python/1020.\351\243\236\345\234\260\347\232\204\346\225\260\351\207\217.py" @@ -1,22 +1,22 @@ -# 从四条边上为 1 的位置向内搜索,将相连的 1 都改为 0,剩下的都是没有连接到边界的 1,计算1的个数所求数量 -class Solution(object): - def numEnclaves(self, A): - d = [(0, 1), (0, -1), (-1, 0), (1, 0)] - m, n = len(A), len(A[0]) - - def dfs(x, y): - A[x][y] = 0 - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and A[nx][ny] == 1: - dfs(nx, ny) - - for i in range(m): - for j in range(n): - if (i == 0 or i == m - 1 or j == 0 or j == n - 1) and A[i][j] == 1: - dfs(i, j) - - res = 0 - for i in range(m): - res += sum(A[i]) +# 从四条边上为 1 的位置向内搜索,将相连的 1 都改为 0,剩下的都是没有连接到边界的 1,计算1的个数所求数量 +class Solution(object): + def numEnclaves(self, A): + d = [(0, 1), (0, -1), (-1, 0), (1, 0)] + m, n = len(A), len(A[0]) + + def dfs(x, y): + A[x][y] = 0 + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and A[nx][ny] == 1: + dfs(nx, ny) + + for i in range(m): + for j in range(n): + if (i == 0 or i == m - 1 or j == 0 or j == n - 1) and A[i][j] == 1: + dfs(i, j) + + res = 0 + for i in range(m): + res += sum(A[i]) return res \ No newline at end of file diff --git "a/leetcode2/1021.\345\210\240\351\231\244\346\234\200\345\244\226\345\261\202\347\232\204\346\213\254\345\217\267.py" "b/leetcode_Python/1021.\345\210\240\351\231\244\346\234\200\345\244\226\345\261\202\347\232\204\346\213\254\345\217\267.py" similarity index 96% rename from "leetcode2/1021.\345\210\240\351\231\244\346\234\200\345\244\226\345\261\202\347\232\204\346\213\254\345\217\267.py" rename to "leetcode_Python/1021.\345\210\240\351\231\244\346\234\200\345\244\226\345\261\202\347\232\204\346\213\254\345\217\267.py" index c1a1c24..8e50881 100644 --- "a/leetcode2/1021.\345\210\240\351\231\244\346\234\200\345\244\226\345\261\202\347\232\204\346\213\254\345\217\267.py" +++ "b/leetcode_Python/1021.\345\210\240\351\231\244\346\234\200\345\244\226\345\261\202\347\232\204\346\213\254\345\217\267.py" @@ -1,15 +1,15 @@ -# 遍历记录左括号和右括号的个数,若相等则凑成一组 -class Solution(object): - def removeOuterParentheses(self, S): - l = r = 0 - res = cur = '' - for s in S: - if s == '(': - l += 1 - if s == ')': - r += 1 - cur += s - if l == r: - res += cur[1:-1] - cur = '' +# 遍历记录左括号和右括号的个数,若相等则凑成一组 +class Solution(object): + def removeOuterParentheses(self, S): + l = r = 0 + res = cur = '' + for s in S: + if s == '(': + l += 1 + if s == ')': + r += 1 + cur += s + if l == r: + res += cur[1:-1] + cur = '' return res \ No newline at end of file diff --git "a/leetcode2/1022.\344\273\216\346\240\271\345\210\260\345\217\266\347\232\204\344\272\214\350\277\233\345\210\266\346\225\260\344\271\213\345\222\214.py" "b/leetcode_Python/1022.\344\273\216\346\240\271\345\210\260\345\217\266\347\232\204\344\272\214\350\277\233\345\210\266\346\225\260\344\271\213\345\222\214.py" similarity index 97% rename from "leetcode2/1022.\344\273\216\346\240\271\345\210\260\345\217\266\347\232\204\344\272\214\350\277\233\345\210\266\346\225\260\344\271\213\345\222\214.py" rename to "leetcode_Python/1022.\344\273\216\346\240\271\345\210\260\345\217\266\347\232\204\344\272\214\350\277\233\345\210\266\346\225\260\344\271\213\345\222\214.py" index 4b88835..bb92da4 100644 --- "a/leetcode2/1022.\344\273\216\346\240\271\345\210\260\345\217\266\347\232\204\344\272\214\350\277\233\345\210\266\346\225\260\344\271\213\345\222\214.py" +++ "b/leetcode_Python/1022.\344\273\216\346\240\271\345\210\260\345\217\266\347\232\204\344\272\214\350\277\233\345\210\266\346\225\260\344\271\213\345\222\214.py" @@ -1,19 +1,19 @@ -# 深度优先搜索,得到所有路径表示的数字,最后转为十进制相加 -class Solution(object): - def sumRootToLeaf(self, root): - global res - res, sum = [], 0 - self.dfs(root, '') - for i in res: - sum += int(i, 2) - return sum - - def dfs(self, root, s): - if not root: - return '' - if not root.left and not root.right: - res.append(s + str(root.val)) - if root.left: - self.dfs(root.left, s + str(root.val)) - if root.right: +# 深度优先搜索,得到所有路径表示的数字,最后转为十进制相加 +class Solution(object): + def sumRootToLeaf(self, root): + global res + res, sum = [], 0 + self.dfs(root, '') + for i in res: + sum += int(i, 2) + return sum + + def dfs(self, root, s): + if not root: + return '' + if not root.left and not root.right: + res.append(s + str(root.val)) + if root.left: + self.dfs(root.left, s + str(root.val)) + if root.right: self.dfs(root.right, s + str(root.val)) \ No newline at end of file diff --git "a/leetcode2/1023.\351\251\274\345\263\260\345\274\217\345\214\271\351\205\215.py" "b/leetcode_Python/1023.\351\251\274\345\263\260\345\274\217\345\214\271\351\205\215.py" similarity index 97% rename from "leetcode2/1023.\351\251\274\345\263\260\345\274\217\345\214\271\351\205\215.py" rename to "leetcode_Python/1023.\351\251\274\345\263\260\345\274\217\345\214\271\351\205\215.py" index 21bc82c..a5aba76 100644 --- "a/leetcode2/1023.\351\251\274\345\263\260\345\274\217\345\214\271\351\205\215.py" +++ "b/leetcode_Python/1023.\351\251\274\345\263\260\345\274\217\345\214\271\351\205\215.py" @@ -1,20 +1,20 @@ -class Solution(object): - def camelMatch(self, queries, pattern): - res = [] - l = len(pattern) - for q in queries: - i = 0 - flag = True - for char in q: - # 与模板字符匹配 - if i < l and char == pattern[i]: - i += 1 - # 与模板字符不匹配,且为大写字母,则待查项与模式串不匹配 - elif 'A' <= char <= 'Z': - flag = False - break - # 模板没有全部匹配 - if i < l: - flag = False - res.append(flag) +class Solution(object): + def camelMatch(self, queries, pattern): + res = [] + l = len(pattern) + for q in queries: + i = 0 + flag = True + for char in q: + # 与模板字符匹配 + if i < l and char == pattern[i]: + i += 1 + # 与模板字符不匹配,且为大写字母,则待查项与模式串不匹配 + elif 'A' <= char <= 'Z': + flag = False + break + # 模板没有全部匹配 + if i < l: + flag = False + res.append(flag) return res \ No newline at end of file diff --git "a/leetcode2/1024.\350\247\206\351\242\221\346\213\274\346\216\245.py" "b/leetcode_Python/1024.\350\247\206\351\242\221\346\213\274\346\216\245.py" similarity index 97% rename from "leetcode2/1024.\350\247\206\351\242\221\346\213\274\346\216\245.py" rename to "leetcode_Python/1024.\350\247\206\351\242\221\346\213\274\346\216\245.py" index 09239cb..70af5bd 100644 --- "a/leetcode2/1024.\350\247\206\351\242\221\346\213\274\346\216\245.py" +++ "b/leetcode_Python/1024.\350\247\206\351\242\221\346\213\274\346\216\245.py" @@ -1,22 +1,22 @@ -# 贪心,每一步都走可到范围内下一步最远的那一步 -class Solution(object): - def videoStitching(self, clips, T): - d = {} - for clip in clips: - # 用字典记录每个起点的最远终点 - d[clip[0]] = max(d.get(clip[0], 0), clip[1]) - res = 1 - start = s = 0 - end = e = reach = d.get(0, 0) - while reach < T: - # 在已有范围内搜寻可到最远距离 - for cur in range(start + 1, end + 1): - if d.get(cur, 0) > reach: - # 记录下一轮的起点和终点 - s, e, reach = cur, d[cur], d[cur] - # 本轮停留在原地 - if s == start and e == end: - return -1 - start, end = s, e - res += 1 +# 贪心,每一步都走可到范围内下一步最远的那一步 +class Solution(object): + def videoStitching(self, clips, T): + d = {} + for clip in clips: + # 用字典记录每个起点的最远终点 + d[clip[0]] = max(d.get(clip[0], 0), clip[1]) + res = 1 + start = s = 0 + end = e = reach = d.get(0, 0) + while reach < T: + # 在已有范围内搜寻可到最远距离 + for cur in range(start + 1, end + 1): + if d.get(cur, 0) > reach: + # 记录下一轮的起点和终点 + s, e, reach = cur, d[cur], d[cur] + # 本轮停留在原地 + if s == start and e == end: + return -1 + start, end = s, e + res += 1 return res \ No newline at end of file diff --git "a/leetcode2/1025.\351\231\244\346\225\260\345\215\232\345\274\210.py" "b/leetcode_Python/1025.\351\231\244\346\225\260\345\215\232\345\274\210.py" similarity index 99% rename from "leetcode2/1025.\351\231\244\346\225\260\345\215\232\345\274\210.py" rename to "leetcode_Python/1025.\351\231\244\346\225\260\345\215\232\345\274\210.py" index ae4781f..b0e7b80 100644 --- "a/leetcode2/1025.\351\231\244\346\225\260\345\215\232\345\274\210.py" +++ "b/leetcode_Python/1025.\351\231\244\346\225\260\345\215\232\345\274\210.py" @@ -1,6 +1,6 @@ -# 如果黑板上写的是奇数,那么下一个人改完之后肯定会变成偶数,因为奇数没有偶数因子并且奇数减去奇数差为偶数。 -# 谁先在黑板上写出3谁就赢了,因为3之后另外一个人只能写2,然后你再写1,另外一个人就没办法写了。 -# 所以如果想赢,必须让自己每次写完之后黑板上都是奇数,因为这样对方就只能写偶数,那么3肯定就会是我方写。 -class Solution(object): - def divisorGame(self, N): +# 如果黑板上写的是奇数,那么下一个人改完之后肯定会变成偶数,因为奇数没有偶数因子并且奇数减去奇数差为偶数。 +# 谁先在黑板上写出3谁就赢了,因为3之后另外一个人只能写2,然后你再写1,另外一个人就没办法写了。 +# 所以如果想赢,必须让自己每次写完之后黑板上都是奇数,因为这样对方就只能写偶数,那么3肯定就会是我方写。 +class Solution(object): + def divisorGame(self, N): return N % 2 == 0 \ No newline at end of file diff --git "a/leetcode2/1026.\350\212\202\347\202\271\344\270\216\345\205\266\347\245\226\345\205\210\344\271\213\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\345\200\274.py" "b/leetcode_Python/1026.\350\212\202\347\202\271\344\270\216\345\205\266\347\245\226\345\205\210\344\271\213\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\345\200\274.py" similarity index 98% rename from "leetcode2/1026.\350\212\202\347\202\271\344\270\216\345\205\266\347\245\226\345\205\210\344\271\213\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\345\200\274.py" rename to "leetcode_Python/1026.\350\212\202\347\202\271\344\270\216\345\205\266\347\245\226\345\205\210\344\271\213\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\345\200\274.py" index 49bc267..502b99f 100644 --- "a/leetcode2/1026.\350\212\202\347\202\271\344\270\216\345\205\266\347\245\226\345\205\210\344\271\213\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\345\200\274.py" +++ "b/leetcode_Python/1026.\350\212\202\347\202\271\344\270\216\345\205\266\347\245\226\345\205\210\344\271\213\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\345\200\274.py" @@ -1,14 +1,14 @@ -# 递归时计算与当前祖先里面的最大值、最小值的差值,即可算出当前节点的最大差值 -# 而一颗树的祖先差值为左子树的祖先差值、右子树的祖先差值、当前节点的祖先差值三者里面的最大值 -class Solution(object): - def maxAncestorDiff(self, root): - return self.dfs(root, root.val, root.val) - - def dfs(self, root, minVal, maxVal): - if not root: - return 0 - val = root.val - root_res = max(abs(minVal - val), abs(maxVal - val)) - left_res = self.dfs(root.left, min(val, minVal), max(val, maxVal)) - right_res = self.dfs(root.right, min(val, minVal), max(val, maxVal)) +# 递归时计算与当前祖先里面的最大值、最小值的差值,即可算出当前节点的最大差值 +# 而一颗树的祖先差值为左子树的祖先差值、右子树的祖先差值、当前节点的祖先差值三者里面的最大值 +class Solution(object): + def maxAncestorDiff(self, root): + return self.dfs(root, root.val, root.val) + + def dfs(self, root, minVal, maxVal): + if not root: + return 0 + val = root.val + root_res = max(abs(minVal - val), abs(maxVal - val)) + left_res = self.dfs(root.left, min(val, minVal), max(val, maxVal)) + right_res = self.dfs(root.right, min(val, minVal), max(val, maxVal)) return max(root_res, left_res, right_res) \ No newline at end of file diff --git "a/leetcode2/1027.\346\234\200\351\225\277\347\255\211\345\267\256\346\225\260\345\210\227.py" "b/leetcode_Python/1027.\346\234\200\351\225\277\347\255\211\345\267\256\346\225\260\345\210\227.py" similarity index 97% rename from "leetcode2/1027.\346\234\200\351\225\277\347\255\211\345\267\256\346\225\260\345\210\227.py" rename to "leetcode_Python/1027.\346\234\200\351\225\277\347\255\211\345\267\256\346\225\260\345\210\227.py" index a2e1295..1b65a53 100644 --- "a/leetcode2/1027.\346\234\200\351\225\277\347\255\211\345\267\256\346\225\260\345\210\227.py" +++ "b/leetcode_Python/1027.\346\234\200\351\225\277\347\255\211\345\267\256\346\225\260\345\210\227.py" @@ -1,35 +1,35 @@ -# 暴力破解 -class Solution(object): - def longestArithSeqLength(self, A): - res = 0 - for i in range(len(A)-2): - for j in range(i+1, len(A)-1): - count = 2 - diff = A[j] - A[i] - cur = A[j] + diff - for k in range(j+1, len(A)): - if A[k] == cur: - count += 1 - cur += diff - res = max(res, count) - return res - - -# 动态规划 -# dp[i][diff]表示以下标为i的元素结尾且公差为diff的等差子序列的最大长度 -# 由于使用数组内存开销太大而且公差可能是负数,所以选择使用字典来代替数组 -class Solution2(object): - # [9, 4, 7, 2, 10] - def longestArithSeqLength(self, A): - n = len(A) - # [{}, {-5: 2}, {3: 2, -2: 2}, {-7: 2, -5: 2, -2: 2}, {8: 2, 1: 2, 3: 3, 6: 2}] - dp = [{} for _ in range(n)] - res = 2 - for i in range(1, n): - for j in range(0, i): - # 计算i下标结尾的元素与前面j下标结尾元素的差 - diff = A[i] - A[j] - # 获取j下标结尾元素,且公差为diff的等差子序列最大长度,再加1得到当前等差子序列最大长度并保存 - dp[i][diff] = dp[j].get(diff, 1) + 1 - res = max(res, dp[i][diff]) - return res +# 暴力破解 +class Solution(object): + def longestArithSeqLength(self, A): + res = 0 + for i in range(len(A)-2): + for j in range(i+1, len(A)-1): + count = 2 + diff = A[j] - A[i] + cur = A[j] + diff + for k in range(j+1, len(A)): + if A[k] == cur: + count += 1 + cur += diff + res = max(res, count) + return res + + +# 动态规划 +# dp[i][diff]表示以下标为i的元素结尾且公差为diff的等差子序列的最大长度 +# 由于使用数组内存开销太大而且公差可能是负数,所以选择使用字典来代替数组 +class Solution2(object): + # [9, 4, 7, 2, 10] + def longestArithSeqLength(self, A): + n = len(A) + # [{}, {-5: 2}, {3: 2, -2: 2}, {-7: 2, -5: 2, -2: 2}, {8: 2, 1: 2, 3: 3, 6: 2}] + dp = [{} for _ in range(n)] + res = 2 + for i in range(1, n): + for j in range(0, i): + # 计算i下标结尾的元素与前面j下标结尾元素的差 + diff = A[i] - A[j] + # 获取j下标结尾元素,且公差为diff的等差子序列最大长度,再加1得到当前等差子序列最大长度并保存 + dp[i][diff] = dp[j].get(diff, 1) + 1 + res = max(res, dp[i][diff]) + return res diff --git "a/leetcode2/1028.\344\273\216\345\205\210\345\272\217\351\201\215\345\216\206\350\277\230\345\216\237\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/1028.\344\273\216\345\205\210\345\272\217\351\201\215\345\216\206\350\277\230\345\216\237\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode2/1028.\344\273\216\345\205\210\345\272\217\351\201\215\345\216\206\350\277\230\345\216\237\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/1028.\344\273\216\345\205\210\345\272\217\351\201\215\345\216\206\350\277\230\345\216\237\344\272\214\345\217\211\346\240\221.py" index 164731b..d3adc3b 100644 --- "a/leetcode2/1028.\344\273\216\345\205\210\345\272\217\351\201\215\345\216\206\350\277\230\345\216\237\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/1028.\344\273\216\345\205\210\345\272\217\351\201\215\345\216\206\350\277\230\345\216\237\344\272\214\345\217\211\346\240\221.py" @@ -1,31 +1,31 @@ -class Solution(object): - def recoverFromPreorder(self, S): - # 遍历字符串,记录结点值和对应层数 - layer, num, queue = 0, '', [] - for char in S: - if char == '-': - if num: - queue.append((num, layer)) - num, layer = '', 0 - layer += 1 - else: - num += char - if num: - queue.append((num, layer)) - - head = TreeNode(None) - # 存放已还原的结点和层数 - stack = [(head, -1)] - for num, layer in queue: - # 层数小于等于最后一个已还原结点时,弹出已还原结点直到其父节点 - while layer <= stack[-1][1]: - stack.pop() - node = TreeNode(num) - parent = stack[-1][0] - stack.append((node, layer)) - # 左孩子优先 - if parent.left: - parent.right = node - else: - parent.left = node +class Solution(object): + def recoverFromPreorder(self, S): + # 遍历字符串,记录结点值和对应层数 + layer, num, queue = 0, '', [] + for char in S: + if char == '-': + if num: + queue.append((num, layer)) + num, layer = '', 0 + layer += 1 + else: + num += char + if num: + queue.append((num, layer)) + + head = TreeNode(None) + # 存放已还原的结点和层数 + stack = [(head, -1)] + for num, layer in queue: + # 层数小于等于最后一个已还原结点时,弹出已还原结点直到其父节点 + while layer <= stack[-1][1]: + stack.pop() + node = TreeNode(num) + parent = stack[-1][0] + stack.append((node, layer)) + # 左孩子优先 + if parent.left: + parent.right = node + else: + parent.left = node return head.left \ No newline at end of file diff --git "a/leetcode/103.\344\272\214\345\217\211\346\240\221\347\232\204\351\224\257\351\275\277\345\275\242\345\261\202\346\254\241\351\201\215\345\216\206.py" "b/leetcode_Python/103.\344\272\214\345\217\211\346\240\221\347\232\204\351\224\257\351\275\277\345\275\242\345\261\202\346\254\241\351\201\215\345\216\206.py" similarity index 97% rename from "leetcode/103.\344\272\214\345\217\211\346\240\221\347\232\204\351\224\257\351\275\277\345\275\242\345\261\202\346\254\241\351\201\215\345\216\206.py" rename to "leetcode_Python/103.\344\272\214\345\217\211\346\240\221\347\232\204\351\224\257\351\275\277\345\275\242\345\261\202\346\254\241\351\201\215\345\216\206.py" index b5aa209..305e314 100644 --- "a/leetcode/103.\344\272\214\345\217\211\346\240\221\347\232\204\351\224\257\351\275\277\345\275\242\345\261\202\346\254\241\351\201\215\345\216\206.py" +++ "b/leetcode_Python/103.\344\272\214\345\217\211\346\240\221\347\232\204\351\224\257\351\275\277\345\275\242\345\261\202\346\254\241\351\201\215\345\216\206.py" @@ -1,20 +1,20 @@ -# 层次遍历,偶数层时该层的值列表反转 -class Solution(object): - def zigzagLevelOrder(self, root): - if not root: - return [] - res, cur_level, next_level, cur_val = [], [root], [], [] - flag = False - while cur_level: - for node in cur_level: - cur_val.append(node.val) - if node.left: - next_level.append(node.left) - if node.right: - next_level.append(node.right) - if flag: - cur_val = cur_val[::-1] - res.append(cur_val) - flag = not flag - cur_level, next_level, cur_val = next_level, [], [] +# 层次遍历,偶数层时该层的值列表反转 +class Solution(object): + def zigzagLevelOrder(self, root): + if not root: + return [] + res, cur_level, next_level, cur_val = [], [root], [], [] + flag = False + while cur_level: + for node in cur_level: + cur_val.append(node.val) + if node.left: + next_level.append(node.left) + if node.right: + next_level.append(node.right) + if flag: + cur_val = cur_val[::-1] + res.append(cur_val) + flag = not flag + cur_level, next_level, cur_val = next_level, [], [] return res \ No newline at end of file diff --git "a/leetcode2/1033.\347\247\273\345\212\250\347\237\263\345\255\220\347\233\264\345\210\260\350\277\236\347\273\255.py" "b/leetcode_Python/1033.\347\247\273\345\212\250\347\237\263\345\255\220\347\233\264\345\210\260\350\277\236\347\273\255.py" similarity index 97% rename from "leetcode2/1033.\347\247\273\345\212\250\347\237\263\345\255\220\347\233\264\345\210\260\350\277\236\347\273\255.py" rename to "leetcode_Python/1033.\347\247\273\345\212\250\347\237\263\345\255\220\347\233\264\345\210\260\350\277\236\347\273\255.py" index 12d4d8b..4d66fc6 100644 --- "a/leetcode2/1033.\347\247\273\345\212\250\347\237\263\345\255\220\347\233\264\345\210\260\350\277\236\347\273\255.py" +++ "b/leetcode_Python/1033.\347\247\273\345\212\250\347\237\263\345\255\220\347\233\264\345\210\260\350\277\236\347\273\255.py" @@ -1,8 +1,8 @@ -class Solution(object): - def numMovesStones(self, a, b, c): - a, b, c = sorted([a, b, c]) - if a+1==b and b+1==c: - return [0, 0] - if a+1==b or a+2==b or b+1==c or b+2==c: - return [1, c-a-2] +class Solution(object): + def numMovesStones(self, a, b, c): + a, b, c = sorted([a, b, c]) + if a+1==b and b+1==c: + return [0, 0] + if a+1==b or a+2==b or b+1==c or b+2==c: + return [1, c-a-2] return [2, c-a-2] \ No newline at end of file diff --git "a/leetcode2/1034.\350\276\271\346\241\206\347\235\200\350\211\262.py" "b/leetcode_Python/1034.\350\276\271\346\241\206\347\235\200\350\211\262.py" similarity index 97% rename from "leetcode2/1034.\350\276\271\346\241\206\347\235\200\350\211\262.py" rename to "leetcode_Python/1034.\350\276\271\346\241\206\347\235\200\350\211\262.py" index 7b20a1e..ef60b7f 100644 --- "a/leetcode2/1034.\350\276\271\346\241\206\347\235\200\350\211\262.py" +++ "b/leetcode_Python/1034.\350\276\271\346\241\206\347\235\200\350\211\262.py" @@ -1,39 +1,39 @@ -# 连通分量边界:与至少一个非连通分量相邻的连通分量,或网格的首尾行列 -class Solution(object): - def colorBorder(self, grid, r0, c0, color): - m = len(grid) - n = len(grid[0]) - ret = [[0] * n for _ in range(m)] - vis = [[0] * n for _ in range(m)] - for i in range(m): - for j in range(n): - ret[i][j] = grid[i][j] - # 代表四个方向的分量 - ds = ((0,1),(1,0),(0,-1),(-1,0)) - t = grid[r0][c0] - - def dfs(i, j): - # 判断当前网格是否已搜寻过 - if not vis[i][j]: - vis[i][j] = True - edge = False - # 遍历四个方向的网格 - for di, dj in ds: - ni, nj = i+di, j+dj - # 某个方向在网格内 - if 0<=ni 1: - y = stones.pop(stones.index(max(stones))) - x = stones.pop(stones.index(max(stones))) - if x < y: - stones.append(y-x) +# 每次取出最大的两个元素相减,结果不为0则添加到列表中 +class Solution(object): + def lastStoneWeight(self, stones): + while len(stones) > 1: + y = stones.pop(stones.index(max(stones))) + x = stones.pop(stones.index(max(stones))) + if x < y: + stones.append(y-x) return stones[0] if stones else 0 \ No newline at end of file diff --git "a/leetcode/105.\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/105.\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" similarity index 98% rename from "leetcode/105.\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/105.\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" index 34e78af..837f48d 100644 --- "a/leetcode/105.\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/105.\344\273\216\345\211\215\345\272\217\344\270\216\344\270\255\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" @@ -1,10 +1,10 @@ -class Solution(object): - # 方法作用极简化:由前序和中序序列得到根结点,并返回根。左右子树有同样需求使用递归 - def buildTree(self, preorder, inorder): - if not preorder and not inorder: - return - root = TreeNode(preorder[0]) - index = inorder.index(preorder[0]) - root.left = self.buildTree(preorder[1:index+1], inorder[:index]) - root.right = self.buildTree(preorder[index+1:], inorder[index+1:]) +class Solution(object): + # 方法作用极简化:由前序和中序序列得到根结点,并返回根。左右子树有同样需求使用递归 + def buildTree(self, preorder, inorder): + if not preorder and not inorder: + return + root = TreeNode(preorder[0]) + index = inorder.index(preorder[0]) + root.left = self.buildTree(preorder[1:index+1], inorder[:index]) + root.right = self.buildTree(preorder[index+1:], inorder[index+1:]) return root \ No newline at end of file diff --git "a/leetcode/106.\344\273\216\344\270\255\345\272\217\344\270\216\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/106.\344\273\216\344\270\255\345\272\217\344\270\216\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" similarity index 98% rename from "leetcode/106.\344\273\216\344\270\255\345\272\217\344\270\216\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/106.\344\273\216\344\270\255\345\272\217\344\270\216\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" index dcb2a59..f235c81 100644 --- "a/leetcode/106.\344\273\216\344\270\255\345\272\217\344\270\216\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/106.\344\273\216\344\270\255\345\272\217\344\270\216\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" @@ -1,10 +1,10 @@ -# 方法作用极简化:由中序和后序序列得到根结点,并返回根。左右子树有同样需求使用递归 -class Solution(object): - def buildTree(self, inorder, postorder): - if not inorder or len(inorder)==0: - return None - root = TreeNode(postorder[-1]) - index = inorder.index(postorder[-1]) - root.left = self.buildTree(inorder[:index], postorder[:index]) - root.right = self.buildTree(inorder[index+1:], postorder[index:-1]) +# 方法作用极简化:由中序和后序序列得到根结点,并返回根。左右子树有同样需求使用递归 +class Solution(object): + def buildTree(self, inorder, postorder): + if not inorder or len(inorder)==0: + return None + root = TreeNode(postorder[-1]) + index = inorder.index(postorder[-1]) + root.left = self.buildTree(inorder[:index], postorder[:index]) + root.right = self.buildTree(inorder[index+1:], postorder[index:-1]) return root \ No newline at end of file diff --git "a/leetcode/107.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206II.py" "b/leetcode_Python/107.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206II.py" similarity index 97% rename from "leetcode/107.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206II.py" rename to "leetcode_Python/107.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206II.py" index dbe3b4f..0fad1ea 100644 --- "a/leetcode/107.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206II.py" +++ "b/leetcode_Python/107.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206II.py" @@ -1,16 +1,16 @@ -# 用数组存放当前层结点,下一层结点,当前层结点值,所有结点值 -class Solution(object): - def levelOrderBottom(self, root): - if not root: - return [] - res, next_list, level, cur_list = [], [], [], [root] - while cur_list: - for node in cur_list: - level.append(node.val) - if node.left: - next_list.append(node.left) - if node.right: - next_list.append(node.right) - res.append(level) - cur_list, next_list, level = next_list, [], [] +# 用数组存放当前层结点,下一层结点,当前层结点值,所有结点值 +class Solution(object): + def levelOrderBottom(self, root): + if not root: + return [] + res, next_list, level, cur_list = [], [], [], [root] + while cur_list: + for node in cur_list: + level.append(node.val) + if node.left: + next_list.append(node.left) + if node.right: + next_list.append(node.right) + res.append(level) + cur_list, next_list, level = next_list, [], [] return res[::-1] \ No newline at end of file diff --git "a/leetcode2/1079.\346\264\273\345\255\227\345\215\260\345\210\267.py" "b/leetcode_Python/1079.\346\264\273\345\255\227\345\215\260\345\210\267.py" similarity index 96% rename from "leetcode2/1079.\346\264\273\345\255\227\345\215\260\345\210\267.py" rename to "leetcode_Python/1079.\346\264\273\345\255\227\345\215\260\345\210\267.py" index 271a6ed..39072ea 100644 --- "a/leetcode2/1079.\346\264\273\345\255\227\345\215\260\345\210\267.py" +++ "b/leetcode_Python/1079.\346\264\273\345\255\227\345\215\260\345\210\267.py" @@ -1,44 +1,44 @@ -# 用集合存放所有可能的字符长度的全排列 -from itertools import permutations -class Solution(object): - def numTilePossibilities(self, tiles): - res = set() - for item_len in range(1, len(tiles)+1): - for item in permutations(tiles, item_len): - res.add(item) - return len(res) - - -# 回溯法,组合所有可能的字符串 -class Solution(object): - def numTilePossibilities(self, tiles): - res = set() - - def genrate(output, tiles): - if output: - res.add(output) - for i in range(len(tiles)): - genrate(output + tiles[i], tiles[:i] + tiles[i+1:]) - - genrate('', tiles) - return len(res) - - -# 回溯法,记录字母个数 -class Solution(object): - def numTilePossibilities(self, tiles): - def dfs(counter): - res = 0 - for i in range(26): - if not counter[i]: - continue - res += 1 - counter[i] -= 1 - res += dfs(counter) - counter[i] += 1 - return res - - counter = [0]*26 - for i in tiles: - counter[ord(i) - ord('A')] += 1 - return dfs(counter) +# 用集合存放所有可能的字符长度的全排列 +from itertools import permutations +class Solution(object): + def numTilePossibilities(self, tiles): + res = set() + for item_len in range(1, len(tiles)+1): + for item in permutations(tiles, item_len): + res.add(item) + return len(res) + + +# 回溯法,组合所有可能的字符串 +class Solution(object): + def numTilePossibilities(self, tiles): + res = set() + + def genrate(output, tiles): + if output: + res.add(output) + for i in range(len(tiles)): + genrate(output + tiles[i], tiles[:i] + tiles[i+1:]) + + genrate('', tiles) + return len(res) + + +# 回溯法,记录字母个数 +class Solution(object): + def numTilePossibilities(self, tiles): + def dfs(counter): + res = 0 + for i in range(26): + if not counter[i]: + continue + res += 1 + counter[i] -= 1 + res += dfs(counter) + counter[i] += 1 + return res + + counter = [0]*26 + for i in tiles: + counter[ord(i) - ord('A')] += 1 + return dfs(counter) diff --git "a/leetcode/108.\345\260\206\346\234\211\345\272\217\346\225\260\347\273\204\350\275\254\346\215\242\344\270\272\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/108.\345\260\206\346\234\211\345\272\217\346\225\260\347\273\204\350\275\254\346\215\242\344\270\272\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 97% rename from "leetcode/108.\345\260\206\346\234\211\345\272\217\346\225\260\347\273\204\350\275\254\346\215\242\344\270\272\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/108.\345\260\206\346\234\211\345\272\217\346\225\260\347\273\204\350\275\254\346\215\242\344\270\272\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index dd1cb57..a2c1044 100644 --- "a/leetcode/108.\345\260\206\346\234\211\345\272\217\346\225\260\347\273\204\350\275\254\346\215\242\344\270\272\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/108.\345\260\206\346\234\211\345\272\217\346\225\260\347\273\204\350\275\254\346\215\242\344\270\272\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,14 +1,14 @@ -# 二叉搜索树:左子树都比根结点小,右子树都比根结点大 - -# 递归思路 -# 1、方法作用极简化:把数组中间的值转化为结点,然后返回该结点 -# 2、处理无和1个结点的情况 -# 3、处理多个结点的情况,重复逻辑使用递归 -class Solution(object): - def sortedArrayToBST(self, nums): - if not nums: - return None - root = TreeNode(nums[len(nums)/2]) - root.left = self.sortedArrayToBST(nums[:len(nums)/2]) - root.right = self.sortedArrayToBST(nums[len(nums)/2+1:]) +# 二叉搜索树:左子树都比根结点小,右子树都比根结点大 + +# 递归思路 +# 1、方法作用极简化:把数组中间的值转化为结点,然后返回该结点 +# 2、处理无和1个结点的情况 +# 3、处理多个结点的情况,重复逻辑使用递归 +class Solution(object): + def sortedArrayToBST(self, nums): + if not nums: + return None + root = TreeNode(nums[len(nums)/2]) + root.left = self.sortedArrayToBST(nums[:len(nums)/2]) + root.right = self.sortedArrayToBST(nums[len(nums)/2+1:]) return root \ No newline at end of file diff --git "a/leetcode2/1080.\346\240\271\345\210\260\345\217\266\350\267\257\345\276\204\344\270\212\347\232\204\344\270\215\350\266\263\350\212\202\347\202\271.py" "b/leetcode_Python/1080.\346\240\271\345\210\260\345\217\266\350\267\257\345\276\204\344\270\212\347\232\204\344\270\215\350\266\263\350\212\202\347\202\271.py" similarity index 97% rename from "leetcode2/1080.\346\240\271\345\210\260\345\217\266\350\267\257\345\276\204\344\270\212\347\232\204\344\270\215\350\266\263\350\212\202\347\202\271.py" rename to "leetcode_Python/1080.\346\240\271\345\210\260\345\217\266\350\267\257\345\276\204\344\270\212\347\232\204\344\270\215\350\266\263\350\212\202\347\202\271.py" index 6f8aa93..5d35b8f 100644 --- "a/leetcode2/1080.\346\240\271\345\210\260\345\217\266\350\267\257\345\276\204\344\270\212\347\232\204\344\270\215\350\266\263\350\212\202\347\202\271.py" +++ "b/leetcode_Python/1080.\346\240\271\345\210\260\345\217\266\350\267\257\345\276\204\344\270\212\347\232\204\344\270\215\350\266\263\350\212\202\347\202\271.py" @@ -1,33 +1,33 @@ -class TreeNode(object): - def __init__(self, x): - self.val = x - self.left = None - self.right = None - - -class Solution(object): - # 方法返回当前节点是否要删除 - def dfs(self, node, sums, limit): - # 递归终止条件 - if not node.left and not node.right: - return node.val + sums < limit - # 默认左右子树都需要删除,后面如果左右节点为空时才能处理 - l_tree_del, r_tree_del = True, True - # 递归判断左右子树是否需要删除 - if node.left: - l_tree_del = self.dfs(node.left, node.val + sums, limit) - if node.right: - r_tree_del = self.dfs(node.right, node.val + sums, limit) - # 需要删除则置位空 - if l_tree_del: - node.left = None - if r_tree_del: - node.right = None - # 左右子树都需要删除时,当前节点就需要删除 - return l_tree_del and r_tree_del - - def sufficientSubset(self, root, limit): - root_del = self.dfs(root, 0, limit) - if root_del: - return None +class TreeNode(object): + def __init__(self, x): + self.val = x + self.left = None + self.right = None + + +class Solution(object): + # 方法返回当前节点是否要删除 + def dfs(self, node, sums, limit): + # 递归终止条件 + if not node.left and not node.right: + return node.val + sums < limit + # 默认左右子树都需要删除,后面如果左右节点为空时才能处理 + l_tree_del, r_tree_del = True, True + # 递归判断左右子树是否需要删除 + if node.left: + l_tree_del = self.dfs(node.left, node.val + sums, limit) + if node.right: + r_tree_del = self.dfs(node.right, node.val + sums, limit) + # 需要删除则置位空 + if l_tree_del: + node.left = None + if r_tree_del: + node.right = None + # 左右子树都需要删除时,当前节点就需要删除 + return l_tree_del and r_tree_del + + def sufficientSubset(self, root, limit): + root_del = self.dfs(root, 0, limit) + if root_del: + return None return root \ No newline at end of file diff --git "a/leetcode/109.\346\234\211\345\272\217\351\223\276\350\241\250\350\275\254\346\215\242\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/109.\346\234\211\345\272\217\351\223\276\350\241\250\350\275\254\346\215\242\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 97% rename from "leetcode/109.\346\234\211\345\272\217\351\223\276\350\241\250\350\275\254\346\215\242\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/109.\346\234\211\345\272\217\351\223\276\350\241\250\350\275\254\346\215\242\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index b37e1fb..843375e 100644 --- "a/leetcode/109.\346\234\211\345\272\217\351\223\276\350\241\250\350\275\254\346\215\242\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/109.\346\234\211\345\272\217\351\223\276\350\241\250\350\275\254\346\215\242\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,17 +1,17 @@ -# 将链表结点值存放在数组中,利用数组值递归构建二叉搜索树 -class Solution(object): - def sortedListToBST(self, head): - res = [] - while head: - res.append(head.val) - head = head.next - return self.buildTree(res) - - def buildTree(self, res): - if not res: - return - # 每次取数组中间值作为结点,数组左右部分给左右子树 - root = TreeNode(res[len(res)/2]) - root.left = self.buildTree(res[:len(res)/2]) - root.right = self.buildTree(res[len(res)/2+1:]) +# 将链表结点值存放在数组中,利用数组值递归构建二叉搜索树 +class Solution(object): + def sortedListToBST(self, head): + res = [] + while head: + res.append(head.val) + head = head.next + return self.buildTree(res) + + def buildTree(self, res): + if not res: + return + # 每次取数组中间值作为结点,数组左右部分给左右子树 + root = TreeNode(res[len(res)/2]) + root.left = self.buildTree(res[:len(res)/2]) + root.right = self.buildTree(res[len(res)/2+1:]) return root \ No newline at end of file diff --git "a/leetcode2/1091.\344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\346\234\200\347\237\255\350\267\257\345\276\204.py" "b/leetcode_Python/1091.\344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\346\234\200\347\237\255\350\267\257\345\276\204.py" similarity index 97% rename from "leetcode2/1091.\344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\346\234\200\347\237\255\350\267\257\345\276\204.py" rename to "leetcode_Python/1091.\344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\346\234\200\347\237\255\350\267\257\345\276\204.py" index b3f771a..d4756e4 100644 --- "a/leetcode2/1091.\344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\346\234\200\347\237\255\350\267\257\345\276\204.py" +++ "b/leetcode_Python/1091.\344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\346\234\200\347\237\255\350\267\257\345\276\204.py" @@ -1,23 +1,23 @@ -class Solution(object): - def shortestPathBinaryMatrix(self, grid): - # 左上角和右下角不是0 - if grid[0][0] or grid[-1][-1]: - return -1 - n, queue, d = len(grid), [(0, 0, 2)], [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] - if n <= 2: - return n - # 从起点开始,广度优先搜索 - for x, y, res in queue: - # 搜索八个方向 - for dx, dy in d: - nx, ny = x+dx, y+dy - if 0 <= nx < n and 0 <= ny < n and not grid[nx][ny]: - # 有一条路径已经到达终点,返回路径长度 - if nx == n-1 and ny == n-1: - return res - # 未到达终点,添加中间位置到队列 - queue += [(nx, ny, res+1)] - # 搜索过的位置置1,防止重复搜索 - grid[nx][ny] = 1 - # 没有路径到达终点 +class Solution(object): + def shortestPathBinaryMatrix(self, grid): + # 左上角和右下角不是0 + if grid[0][0] or grid[-1][-1]: + return -1 + n, queue, d = len(grid), [(0, 0, 2)], [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] + if n <= 2: + return n + # 从起点开始,广度优先搜索 + for x, y, res in queue: + # 搜索八个方向 + for dx, dy in d: + nx, ny = x+dx, y+dy + if 0 <= nx < n and 0 <= ny < n and not grid[nx][ny]: + # 有一条路径已经到达终点,返回路径长度 + if nx == n-1 and ny == n-1: + return res + # 未到达终点,添加中间位置到队列 + queue += [(nx, ny, res+1)] + # 搜索过的位置置1,防止重复搜索 + grid[nx][ny] = 1 + # 没有路径到达终点 return -1 \ No newline at end of file diff --git "a/leetcode/110.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/110.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/110.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/110.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" index 713e20c..6c2850c 100644 --- "a/leetcode/110.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/110.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" @@ -1,12 +1,12 @@ -class Solution(object): - # 判断左子树和右子树的高度,并递归判断左右结点的左右子树高度 - def isBalanced(self, root): - if not root: - return True - return abs(self.high(root.left) - self.high(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right) - - # 求树的高度 - def high(self, root): - if not root: - return 0 +class Solution(object): + # 判断左子树和右子树的高度,并递归判断左右结点的左右子树高度 + def isBalanced(self, root): + if not root: + return True + return abs(self.high(root.left) - self.high(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right) + + # 求树的高度 + def high(self, root): + if not root: + return 0 return 1 + max(self.high(root.left), self.high(root.right)) \ No newline at end of file diff --git "a/leetcode2/1109.\350\210\252\347\217\255\351\242\204\350\256\242\347\273\237\350\256\241.py" "b/leetcode_Python/1109.\350\210\252\347\217\255\351\242\204\350\256\242\347\273\237\350\256\241.py" similarity index 97% rename from "leetcode2/1109.\350\210\252\347\217\255\351\242\204\350\256\242\347\273\237\350\256\241.py" rename to "leetcode_Python/1109.\350\210\252\347\217\255\351\242\204\350\256\242\347\273\237\350\256\241.py" index 679a5fd..db231f0 100644 --- "a/leetcode2/1109.\350\210\252\347\217\255\351\242\204\350\256\242\347\273\237\350\256\241.py" +++ "b/leetcode_Python/1109.\350\210\252\347\217\255\351\242\204\350\256\242\347\273\237\350\256\241.py" @@ -1,12 +1,12 @@ -# 前缀和解法,类似公交站记录上车人数和下车人数,每一站的人数为上一站的人数加上当前站的变化人数 -class Solution(object): - def corpFlightBookings(self, bookings, n): - res = [0]*n - for b in bookings: - l, r = b[0]-1, b[1] - res[l] += b[2] - if r < n: - res[r] -= b[2] - for i in range(1, n): - res[i] += res[i-1] +# 前缀和解法,类似公交站记录上车人数和下车人数,每一站的人数为上一站的人数加上当前站的变化人数 +class Solution(object): + def corpFlightBookings(self, bookings, n): + res = [0]*n + for b in bookings: + l, r = b[0]-1, b[1] + res[l] += b[2] + if r < n: + res[r] -= b[2] + for i in range(1, n): + res[i] += res[i-1] return res \ No newline at end of file diff --git "a/leetcode/111.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.py" "b/leetcode_Python/111.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.py" similarity index 97% rename from "leetcode/111.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.py" rename to "leetcode_Python/111.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.py" index 5f47021..ac78224 100644 --- "a/leetcode/111.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.py" +++ "b/leetcode_Python/111.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.py" @@ -1,22 +1,22 @@ -# 写法一:递归累加求出每个结点的深度 -class Solution(object): - def minDepth(self, root): - if not root: - return 0 - if root.left and root.right: - return 1 + min(self.minDepth(root.left), self.minDepth(root.right)) - elif root.left: - return 1 + self.minDepth(root.left) - elif root.right: - return 1 + self.minDepth(root.right) - else: - return 1 - -# 写法二 -class Solution(object): - def minDepth(self, root): - if not root: - return 0 - depth = map(self.minDepth, (root.left, root.right)) - # 如果一个子树的深度为0,则取另一个子树为最小深度。如果两个子树深度都不为0,则取较小者为最小深度。 +# 写法一:递归累加求出每个结点的深度 +class Solution(object): + def minDepth(self, root): + if not root: + return 0 + if root.left and root.right: + return 1 + min(self.minDepth(root.left), self.minDepth(root.right)) + elif root.left: + return 1 + self.minDepth(root.left) + elif root.right: + return 1 + self.minDepth(root.right) + else: + return 1 + +# 写法二 +class Solution(object): + def minDepth(self, root): + if not root: + return 0 + depth = map(self.minDepth, (root.left, root.right)) + # 如果一个子树的深度为0,则取另一个子树为最小深度。如果两个子树深度都不为0,则取较小者为最小深度。 return 1 + (min(depth) or max(depth)) \ No newline at end of file diff --git "a/leetcode2/1114.\346\214\211\345\272\217\346\211\223\345\215\260.py" "b/leetcode_Python/1114.\346\214\211\345\272\217\346\211\223\345\215\260.py" similarity index 95% rename from "leetcode2/1114.\346\214\211\345\272\217\346\211\223\345\215\260.py" rename to "leetcode_Python/1114.\346\214\211\345\272\217\346\211\223\345\215\260.py" index 2b9e2de..a28b04f 100644 --- "a/leetcode2/1114.\346\214\211\345\272\217\346\211\223\345\215\260.py" +++ "b/leetcode_Python/1114.\346\214\211\345\272\217\346\211\223\345\215\260.py" @@ -1,19 +1,19 @@ -# 使用全局变量作为标记 -class Foo(object): - def __init__(self): - self.flag = 1 - - def first(self, printFirst): - printFirst() - self.flag = 2 - - def second(self, printSecond): - while self.flag != 2: - pass - printSecond() - self.flag = 3 - - def third(self, printThird): - while self.flag != 3: - pass +# 使用全局变量作为标记 +class Foo(object): + def __init__(self): + self.flag = 1 + + def first(self, printFirst): + printFirst() + self.flag = 2 + + def second(self, printSecond): + while self.flag != 2: + pass + printSecond() + self.flag = 3 + + def third(self, printThird): + while self.flag != 3: + pass printThird() \ No newline at end of file diff --git "a/leetcode/112.\350\267\257\345\276\204\346\200\273\345\222\214.py" "b/leetcode_Python/112.\350\267\257\345\276\204\346\200\273\345\222\214.py" similarity index 97% rename from "leetcode/112.\350\267\257\345\276\204\346\200\273\345\222\214.py" rename to "leetcode_Python/112.\350\267\257\345\276\204\346\200\273\345\222\214.py" index 4ab39bd..e697e65 100644 --- "a/leetcode/112.\350\267\257\345\276\204\346\200\273\345\222\214.py" +++ "b/leetcode_Python/112.\350\267\257\345\276\204\346\200\273\345\222\214.py" @@ -1,16 +1,16 @@ -class Solution(object): - def hasPathSum(self, root, sum): - if not root: - return False - return (not root.left and not root.right and root.val == sum) \ - or self.hasPathSum(root.left, sum-root.val) \ - or self.hasPathSum(root.right, sum-root.val) - -################ 递归思路 ################ -# 方法作用极简化:先判断无结点和1个结点的情况。返回结点与给定值是否相等的判断 -# 由于其他结点需要同样操作,使用递归 -class Solution(object): - def hasPathSum(self, root, sum): - if not root: - return False +class Solution(object): + def hasPathSum(self, root, sum): + if not root: + return False + return (not root.left and not root.right and root.val == sum) \ + or self.hasPathSum(root.left, sum-root.val) \ + or self.hasPathSum(root.right, sum-root.val) + +################ 递归思路 ################ +# 方法作用极简化:先判断无结点和1个结点的情况。返回结点与给定值是否相等的判断 +# 由于其他结点需要同样操作,使用递归 +class Solution(object): + def hasPathSum(self, root, sum): + if not root: + return False return root.val == sum \ No newline at end of file diff --git "a/leetcode2/1123.\346\234\200\346\267\261\345\217\266\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" "b/leetcode_Python/1123.\346\234\200\346\267\261\345\217\266\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" similarity index 96% rename from "leetcode2/1123.\346\234\200\346\267\261\345\217\266\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" rename to "leetcode_Python/1123.\346\234\200\346\267\261\345\217\266\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" index 1f95704..993cb12 100644 --- "a/leetcode2/1123.\346\234\200\346\267\261\345\217\266\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" +++ "b/leetcode_Python/1123.\346\234\200\346\267\261\345\217\266\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" @@ -1,24 +1,24 @@ -class TreeNode(object): - def __init__(self, x): - self.val = x - self.left = None - self.right = None - - -# 深度优先搜索,从下往上计算深度,比较左右子树的深度,最近公共祖先的左右子树等高 -class Solution(object): - def lcaDeepestLeaves(self, root): - def dfs(root): - if not root: - return None, 0 - l_node, l_depth = dfs(root.left) - r_node, r_depth = dfs(root.right) - if l_depth > r_depth: - return l_node, l_depth + 1 - elif l_depth < r_depth: - return r_node, r_depth + 1 - else: - return root, l_depth + 1 - - node, _ = dfs(root) +class TreeNode(object): + def __init__(self, x): + self.val = x + self.left = None + self.right = None + + +# 深度优先搜索,从下往上计算深度,比较左右子树的深度,最近公共祖先的左右子树等高 +class Solution(object): + def lcaDeepestLeaves(self, root): + def dfs(root): + if not root: + return None, 0 + l_node, l_depth = dfs(root.left) + r_node, r_depth = dfs(root.right) + if l_depth > r_depth: + return l_node, l_depth + 1 + elif l_depth < r_depth: + return r_node, r_depth + 1 + else: + return root, l_depth + 1 + + node, _ = dfs(root) return node \ No newline at end of file diff --git "a/leetcode/113.\350\267\257\345\276\204\346\200\273\345\222\214II.py" "b/leetcode_Python/113.\350\267\257\345\276\204\346\200\273\345\222\214II.py" similarity index 97% rename from "leetcode/113.\350\267\257\345\276\204\346\200\273\345\222\214II.py" rename to "leetcode_Python/113.\350\267\257\345\276\204\346\200\273\345\222\214II.py" index ccbaf91..eb3f683 100644 --- "a/leetcode/113.\350\267\257\345\276\204\346\200\273\345\222\214II.py" +++ "b/leetcode_Python/113.\350\267\257\345\276\204\346\200\273\345\222\214II.py" @@ -1,20 +1,20 @@ -# 类似129题 -# 搜到叶子节点判断是否符合条件,若符合条件则将记录该路径的集合添加到结果集合中 -class Solution(object): - - def pathSum(self, root, sum): - global res - res = [] - self.dfs(root, sum, []) - return res - - def dfs(self, root, sum, cur_list): - if not root: - return - sum -= root.val - if sum==0 and not root.left and not root.right: - res.append(cur_list + [root.val]) - if root.left: - self.dfs(root.left, sum, cur_list + [root.val]) - if root.right: +# 类似129题 +# 搜到叶子节点判断是否符合条件,若符合条件则将记录该路径的集合添加到结果集合中 +class Solution(object): + + def pathSum(self, root, sum): + global res + res = [] + self.dfs(root, sum, []) + return res + + def dfs(self, root, sum, cur_list): + if not root: + return + sum -= root.val + if sum==0 and not root.left and not root.right: + res.append(cur_list + [root.val]) + if root.left: + self.dfs(root.left, sum, cur_list + [root.val]) + if root.right: self.dfs(root.right, sum, cur_list + [root.val]) \ No newline at end of file diff --git "a/leetcode/114.\344\272\214\345\217\211\346\240\221\345\261\225\345\274\200\344\270\272\351\223\276\350\241\250.py" "b/leetcode_Python/114.\344\272\214\345\217\211\346\240\221\345\261\225\345\274\200\344\270\272\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/114.\344\272\214\345\217\211\346\240\221\345\261\225\345\274\200\344\270\272\351\223\276\350\241\250.py" rename to "leetcode_Python/114.\344\272\214\345\217\211\346\240\221\345\261\225\345\274\200\344\270\272\351\223\276\350\241\250.py" index 0d87ed3..8b90ace 100644 --- "a/leetcode/114.\344\272\214\345\217\211\346\240\221\345\261\225\345\274\200\344\270\272\351\223\276\350\241\250.py" +++ "b/leetcode_Python/114.\344\272\214\345\217\211\346\240\221\345\261\225\345\274\200\344\270\272\351\223\276\350\241\250.py" @@ -1,36 +1,36 @@ -# 方法一:前序遍历得到结点数组,令每个结点的左孩子为空,右孩子为数组的下一个结点 -class Solution(object): - def flatten(self, root): - - def preorder(root): - if root: - res.append(root) - preorder(root.left) - preorder(root.right) - - if not root: - return - global res - res = [] - preorder(root) - for i in range(len(res)-1): - res[i].left = None - res[i].right = res[i+1] - res[-1].left = None - res[-1].right = None - -# 方法二:复制左右子树,裁剪左子树,将左子树拼接到根与右子树中间 -class Solution(object): - def flatten(self, root): - if not root: - return - left_node = root.left - right_node = root.right - root.left = None - self.flatten(left_node) - self.flatten(right_node) - if left_node: - root.right = left_node - while left_node.right: - left_node = left_node.right +# 方法一:前序遍历得到结点数组,令每个结点的左孩子为空,右孩子为数组的下一个结点 +class Solution(object): + def flatten(self, root): + + def preorder(root): + if root: + res.append(root) + preorder(root.left) + preorder(root.right) + + if not root: + return + global res + res = [] + preorder(root) + for i in range(len(res)-1): + res[i].left = None + res[i].right = res[i+1] + res[-1].left = None + res[-1].right = None + +# 方法二:复制左右子树,裁剪左子树,将左子树拼接到根与右子树中间 +class Solution(object): + def flatten(self, root): + if not root: + return + left_node = root.left + right_node = root.right + root.left = None + self.flatten(left_node) + self.flatten(right_node) + if left_node: + root.right = left_node + while left_node.right: + left_node = left_node.right left_node.right = right_node \ No newline at end of file diff --git "a/leetcode/116.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271.py" "b/leetcode_Python/116.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271.py" similarity index 97% rename from "leetcode/116.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271.py" rename to "leetcode_Python/116.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271.py" index f65fd67..33c8a09 100644 --- "a/leetcode/116.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271.py" +++ "b/leetcode_Python/116.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271.py" @@ -1,15 +1,15 @@ -# 层次遍历得到每一层的结点,每个结点的next指针指向列表的下一个结点 -class Solution: - def connect(self, root): - if not root: - return - cur_level, next_level = [root], [] - while cur_level: - for node in cur_level: - if node.left: - next_level.append(node.left) - if node.right: - next_level.append(node.right) - for i in range(len(cur_level)-1): - cur_level[i].next = cur_level[i+1] +# 层次遍历得到每一层的结点,每个结点的next指针指向列表的下一个结点 +class Solution: + def connect(self, root): + if not root: + return + cur_level, next_level = [root], [] + while cur_level: + for node in cur_level: + if node.left: + next_level.append(node.left) + if node.right: + next_level.append(node.right) + for i in range(len(cur_level)-1): + cur_level[i].next = cur_level[i+1] cur_level, next_level = next_level, [] \ No newline at end of file diff --git "a/leetcode2/1162.\345\234\260\345\233\276\345\210\206\346\236\220.py" "b/leetcode_Python/1162.\345\234\260\345\233\276\345\210\206\346\236\220.py" similarity index 97% rename from "leetcode2/1162.\345\234\260\345\233\276\345\210\206\346\236\220.py" rename to "leetcode_Python/1162.\345\234\260\345\233\276\345\210\206\346\236\220.py" index b599b65..6dff45c 100644 --- "a/leetcode2/1162.\345\234\260\345\233\276\345\210\206\346\236\220.py" +++ "b/leetcode_Python/1162.\345\234\260\345\233\276\345\210\206\346\236\220.py" @@ -1,25 +1,25 @@ -# 广度优先搜索,从1开始,向四周搜索0,并记录每个0的搜索步数,返回最大的搜索步数 -class Solution(object): - def maxDistance(self, grid): - m, n = len(grid), len(grid[0]) - if sum([sum(grid[i]) for i in range(m)]) in [0, m * n]: - return -1 - - q, res = [], [[-1] * n for _ in range(m)] - d = [(1, 0), (-1, 0), (0, 1), (0, -1)] - - for i in range(m): - for j in range(n): - if grid[i][j] == 1: - res[i][j] = 0 - q.append((i, j)) - - while q: - x, y = q.pop(0) - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and res[nx][ny] == -1: - res[nx][ny] = res[x][y] + 1 - q.append((nx, ny)) - +# 广度优先搜索,从1开始,向四周搜索0,并记录每个0的搜索步数,返回最大的搜索步数 +class Solution(object): + def maxDistance(self, grid): + m, n = len(grid), len(grid[0]) + if sum([sum(grid[i]) for i in range(m)]) in [0, m * n]: + return -1 + + q, res = [], [[-1] * n for _ in range(m)] + d = [(1, 0), (-1, 0), (0, 1), (0, -1)] + + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + res[i][j] = 0 + q.append((i, j)) + + while q: + x, y = q.pop(0) + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and res[nx][ny] == -1: + res[nx][ny] = res[x][y] + 1 + q.append((nx, ny)) + return max([max(res[i]) for i in range(m)]) \ No newline at end of file diff --git "a/leetcode/117.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271II.py" "b/leetcode_Python/117.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271II.py" similarity index 97% rename from "leetcode/117.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271II.py" rename to "leetcode_Python/117.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271II.py" index 9a150ef..e62f7bf 100644 --- "a/leetcode/117.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271II.py" +++ "b/leetcode_Python/117.\345\241\253\345\205\205\345\220\214\344\270\200\345\261\202\347\232\204\345\205\204\345\274\237\350\212\202\347\202\271II.py" @@ -1,19 +1,19 @@ -class Solution: - def connect(self, root): - global res - res = [] - self.addLayer(root, 0) - for level in res: - for i in range(len(level)-1): - level[i].next = level[i+1] - - def addLayer(self, root, level): - if not root: - return - # 有下一层时添加一个数组存放下一层结点 - if len(res) < level+1: - res.append([]) - # 将结点添加到对应层的数组中 - res[level].append(root) - self.addLayer(root.left, level+1) +class Solution: + def connect(self, root): + global res + res = [] + self.addLayer(root, 0) + for level in res: + for i in range(len(level)-1): + level[i].next = level[i+1] + + def addLayer(self, root, level): + if not root: + return + # 有下一层时添加一个数组存放下一层结点 + if len(res) < level+1: + res.append([]) + # 将结点添加到对应层的数组中 + res[level].append(root) + self.addLayer(root.left, level+1) self.addLayer(root.right, level+1) \ No newline at end of file diff --git "a/leetcode/118.\346\235\250\350\276\211\344\270\211\350\247\222.py" "b/leetcode_Python/118.\346\235\250\350\276\211\344\270\211\350\247\222.py" similarity index 97% rename from "leetcode/118.\346\235\250\350\276\211\344\270\211\350\247\222.py" rename to "leetcode_Python/118.\346\235\250\350\276\211\344\270\211\350\247\222.py" index cb91e67..7a8adb4 100644 --- "a/leetcode/118.\346\235\250\350\276\211\344\270\211\350\247\222.py" +++ "b/leetcode_Python/118.\346\235\250\350\276\211\344\270\211\350\247\222.py" @@ -1,12 +1,12 @@ -# 每次先初始化当前行的数组,再将求和结果代入 -class Solution(object): - def generate(self, numRows): - res = [] - for i in range(numRows): - cur = [1]*(i+1) - if i >= 2: - for j in range(1, i): - cur[j] = pre[j] + pre[j-1] - res.append(cur) - pre = cur +# 每次先初始化当前行的数组,再将求和结果代入 +class Solution(object): + def generate(self, numRows): + res = [] + for i in range(numRows): + cur = [1]*(i+1) + if i >= 2: + for j in range(1, i): + cur[j] = pre[j] + pre[j-1] + res.append(cur) + pre = cur return res \ No newline at end of file diff --git "a/leetcode/119.\346\235\250\350\276\211\344\270\211\350\247\222II.py" "b/leetcode_Python/119.\346\235\250\350\276\211\344\270\211\350\247\222II.py" similarity index 97% rename from "leetcode/119.\346\235\250\350\276\211\344\270\211\350\247\222II.py" rename to "leetcode_Python/119.\346\235\250\350\276\211\344\270\211\350\247\222II.py" index 875005c..151f00c 100644 --- "a/leetcode/119.\346\235\250\350\276\211\344\270\211\350\247\222II.py" +++ "b/leetcode_Python/119.\346\235\250\350\276\211\344\270\211\350\247\222II.py" @@ -1,9 +1,9 @@ -class Solution(object): - def getRow(self, rowIndex): - for k in range(rowIndex+1): - cur = [1]*(k+1) - if k >= 2: - for i in range(1, k): - cur[i] = pre[i] + pre[i-1] - pre = cur +class Solution(object): + def getRow(self, rowIndex): + for k in range(rowIndex+1): + cur = [1]*(k+1) + if k >= 2: + for i in range(1, k): + cur[i] = pre[i] + pre[i-1] + pre = cur return cur \ No newline at end of file diff --git "a/leetcode/120.\344\270\211\350\247\222\345\275\242\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" "b/leetcode_Python/120.\344\270\211\350\247\222\345\275\242\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" similarity index 97% rename from "leetcode/120.\344\270\211\350\247\222\345\275\242\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" rename to "leetcode_Python/120.\344\270\211\350\247\222\345\275\242\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" index fa90516..d6be07d 100644 --- "a/leetcode/120.\344\270\211\350\247\222\345\275\242\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" +++ "b/leetcode_Python/120.\344\270\211\350\247\222\345\275\242\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" @@ -1,35 +1,35 @@ -# 动态规划,原地修改,自底向上,记录每个位置的最短路径 -class Solution(object): - def minimumTotal(self, triangle): - for i in range(len(triangle)-2, -1, -1): - for j in range(i+1): - triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]) - return triangle[0][0] - - -# 自底向上,使用一维数组记录最短路径状态 -class Solution2(object): - def minimumTotal(self, triangle): - # 加1不用初始化最后一层 - dp = [0] * (len(triangle)+1) - for i in range(len(triangle)-1, -1, -1): - for j in range(i+1): - dp[j] = triangle[i][j] + min(dp[j], dp[j+1]) - return dp[0] - - -# 自顶向下,原地修改 -class Solution3(object): - def minimumTotal(self, triangle): - for i in range(1, len(triangle)): - for j in range(i+1): - # 行首元素 - if j == 0: - triangle[i][j] += triangle[i-1][j] - # 行尾元素 - elif j == len(triangle[i])-1: - triangle[i][j] += triangle[i-1][j-1] - # 内部元素 - else: - triangle[i][j] += min(triangle[i-1][j], triangle[i-1][j-1]) +# 动态规划,原地修改,自底向上,记录每个位置的最短路径 +class Solution(object): + def minimumTotal(self, triangle): + for i in range(len(triangle)-2, -1, -1): + for j in range(i+1): + triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]) + return triangle[0][0] + + +# 自底向上,使用一维数组记录最短路径状态 +class Solution2(object): + def minimumTotal(self, triangle): + # 加1不用初始化最后一层 + dp = [0] * (len(triangle)+1) + for i in range(len(triangle)-1, -1, -1): + for j in range(i+1): + dp[j] = triangle[i][j] + min(dp[j], dp[j+1]) + return dp[0] + + +# 自顶向下,原地修改 +class Solution3(object): + def minimumTotal(self, triangle): + for i in range(1, len(triangle)): + for j in range(i+1): + # 行首元素 + if j == 0: + triangle[i][j] += triangle[i-1][j] + # 行尾元素 + elif j == len(triangle[i])-1: + triangle[i][j] += triangle[i-1][j-1] + # 内部元素 + else: + triangle[i][j] += min(triangle[i-1][j], triangle[i-1][j-1]) return min(triangle[-1]) \ No newline at end of file diff --git "a/leetcode/121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" "b/leetcode_Python/121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" similarity index 97% rename from "leetcode/121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" rename to "leetcode_Python/121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" index 46dc639..2574c00 100644 --- "a/leetcode/121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" +++ "b/leetcode_Python/121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" @@ -1,8 +1,8 @@ -# 遍历列表,记录价格最小值,保存最大差值 -class Solution(object): - def maxProfit(self, prices): - min_p, max_p = 99999, 0 - for i in prices: - min_p = min(min_p, i) - max_p = max(max_p, i-min_p) +# 遍历列表,记录价格最小值,保存最大差值 +class Solution(object): + def maxProfit(self, prices): + min_p, max_p = 99999, 0 + for i in prices: + min_p = min(min_p, i) + max_p = max(max_p, i-min_p) return max_p \ No newline at end of file diff --git "a/leetcode/122.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272II.py" "b/leetcode_Python/122.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272II.py" similarity index 97% rename from "leetcode/122.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272II.py" rename to "leetcode_Python/122.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272II.py" index 680c194..9027488 100644 --- "a/leetcode/122.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272II.py" +++ "b/leetcode_Python/122.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272II.py" @@ -1,9 +1,9 @@ -# 理解规律,后一天价格减前一天价格大于0,则累加利润 -class Solution(object): - def maxProfit(self, prices): - pro = 0 - for day in range(len(prices)-1): - differ = prices[day+1] - prices[day] - if differ > 0: - pro += differ +# 理解规律,后一天价格减前一天价格大于0,则累加利润 +class Solution(object): + def maxProfit(self, prices): + pro = 0 + for day in range(len(prices)-1): + differ = prices[day+1] - prices[day] + if differ > 0: + pro += differ return pro \ No newline at end of file diff --git "a/leetcode/124.\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.py" "b/leetcode_Python/124.\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.py" similarity index 97% rename from "leetcode/124.\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.py" rename to "leetcode_Python/124.\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.py" index 200fb2f..a729353 100644 --- "a/leetcode/124.\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.py" +++ "b/leetcode_Python/124.\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.py" @@ -1,27 +1,27 @@ -class Solution(object): - def maxPathSum(self, root): - if not root: - return 0 - self.res = root.val - self.findmax(root) - return self.res - - def findmax(self, root): - if not root: - return 0 - left = self.findmax(root.left) - max_left = left if left>0 else 0 - right = self.findmax(root.right) - max_right = right if right>0 else 0 - self.res = max(self.res, max_left + max_right + root.val) - return max(max_left, max_right) + root.val - -##################### 递归思路 ####################### -# 方法作用极简化:先判断无结点和1个结点的情况 -# 方法作用描述:参数给一个结点,将结点值与结果值比较取最大保存,然后返回该结点值 -# 递归:由于需要累加左右子树结点值,使用递归得到每个结点的值并将结果累加 -def findmax(self, root): - if not root: - return 0 - self.res = max(self.res, root.val) +class Solution(object): + def maxPathSum(self, root): + if not root: + return 0 + self.res = root.val + self.findmax(root) + return self.res + + def findmax(self, root): + if not root: + return 0 + left = self.findmax(root.left) + max_left = left if left>0 else 0 + right = self.findmax(root.right) + max_right = right if right>0 else 0 + self.res = max(self.res, max_left + max_right + root.val) + return max(max_left, max_right) + root.val + +##################### 递归思路 ####################### +# 方法作用极简化:先判断无结点和1个结点的情况 +# 方法作用描述:参数给一个结点,将结点值与结果值比较取最大保存,然后返回该结点值 +# 递归:由于需要累加左右子树结点值,使用递归得到每个结点的值并将结果累加 +def findmax(self, root): + if not root: + return 0 + self.res = max(self.res, root.val) return root.val \ No newline at end of file diff --git "a/leetcode/125.\351\252\214\350\257\201\345\233\236\346\226\207\344\270\262.py" "b/leetcode_Python/125.\351\252\214\350\257\201\345\233\236\346\226\207\344\270\262.py" similarity index 97% rename from "leetcode/125.\351\252\214\350\257\201\345\233\236\346\226\207\344\270\262.py" rename to "leetcode_Python/125.\351\252\214\350\257\201\345\233\236\346\226\207\344\270\262.py" index 31862e1..88e4e58 100644 --- "a/leetcode/125.\351\252\214\350\257\201\345\233\236\346\226\207\344\270\262.py" +++ "b/leetcode_Python/125.\351\252\214\350\257\201\345\233\236\346\226\207\344\270\262.py" @@ -1,15 +1,15 @@ -# 方法一:直接判断并提取字母数字 -class Solution(object): - def isPalindrome(self, s): - res = '' - for i in s: - if 'a' <= i <= 'z' or 'A' <= i <= 'Z' or '0' <= i <= '9': - res += i - res = res.lower() - return res == res[::-1] - -# 方法二:由方法isalnum()提取字母数字 -class Solution(object): - def isPalindrome(self, s): - s = ''.join(i for i in s if i.isalnum()).lower() +# 方法一:直接判断并提取字母数字 +class Solution(object): + def isPalindrome(self, s): + res = '' + for i in s: + if 'a' <= i <= 'z' or 'A' <= i <= 'Z' or '0' <= i <= '9': + res += i + res = res.lower() + return res == res[::-1] + +# 方法二:由方法isalnum()提取字母数字 +class Solution(object): + def isPalindrome(self, s): + s = ''.join(i for i in s if i.isalnum()).lower() return s == s[::-1] \ No newline at end of file diff --git "a/leetcode/129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.py" "b/leetcode_Python/129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.py" similarity index 97% rename from "leetcode/129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.py" rename to "leetcode_Python/129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.py" index 965047b..dcca702 100644 --- "a/leetcode/129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.py" +++ "b/leetcode_Python/129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.py" @@ -1,21 +1,21 @@ -# 类似113题 -# 深度优先搜索,得到所有路径的数组,再将每个路径组合成数字相加 -class Solution(object): - def sumNumbers(self, root): - global res - res = [] - self.dfs(root, []) - sum = 0 - for path in res: - sum += int(''.join(str(i) for i in path)) - return sum - - def dfs(self, root, cur_list): - if not root: - return [] - if not root.left and not root.right: - res.append(cur_list + [root.val]) - if root.left: - self.dfs(root.left, cur_list + [root.val]) - if root.right: +# 类似113题 +# 深度优先搜索,得到所有路径的数组,再将每个路径组合成数字相加 +class Solution(object): + def sumNumbers(self, root): + global res + res = [] + self.dfs(root, []) + sum = 0 + for path in res: + sum += int(''.join(str(i) for i in path)) + return sum + + def dfs(self, root, cur_list): + if not root: + return [] + if not root.left and not root.right: + res.append(cur_list + [root.val]) + if root.left: + self.dfs(root.left, cur_list + [root.val]) + if root.right: self.dfs(root.right, cur_list + [root.val]) \ No newline at end of file diff --git "a/leetcode/130.\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" "b/leetcode_Python/130.\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" similarity index 97% rename from "leetcode/130.\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" rename to "leetcode_Python/130.\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" index 2405d8a..b458cbf 100644 --- "a/leetcode/130.\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" +++ "b/leetcode_Python/130.\350\242\253\345\233\264\347\273\225\347\232\204\345\214\272\345\237\237.py" @@ -1,69 +1,69 @@ -# 深度优先搜索 -class Solution(object): - def solve(self, board): - # 判断为空的情况 - if not board: - return [] - - m, n = len(board), len(board[0]) - d = ((1, 0), (-1, 0), (0, 1), (0, -1)) - - def dfs(x, y): - # 变换符号为'Y' - board[x][y] = 'Y' - # 对四个方向进行搜索 - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == 'O': - dfs(nx, ny) - - for i in range(m): - for j in range(n): - # 对四条边上的'O'进行深度优先搜索 - if i-1<0 or i+1==m or j-1<0 or j+1==n: - if board[i][j] == 'O': - dfs(i, j) - - # 再次遍历矩阵,将被包围的'O'改为'X',将'Y'改为原来的'O' - for i in range(m): - for j in range(n): - if board[i][j] == 'O': - board[i][j] = 'X' - if board[i][j] == 'Y': - board[i][j] = 'O' - - return board - - -# 广度优先搜索 -import collections -class Solution2(object): - def solve(self, board): - if not board: - return [] - - m, n = len(board), len(board[0]) - d = ((1, 0), (-1, 0), (0, 1), (0, -1)) - - for i in range(m): - for j in range(n): - if i-1<0 or i+1==m or j-1<0 or j+1==n: - if board[i][j] == 'O': - q = collections.deque() - q.appendleft((i, j)) - while q: - x, y = q.pop() - board[x][y] = 'Y' - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == 'O': - q.appendleft((nx, ny)) - - for i in range(m): - for j in range(n): - if board[i][j] == 'O': - board[i][j] = 'X' - if board[i][j] == 'Y': - board[i][j] = 'O' - +# 深度优先搜索 +class Solution(object): + def solve(self, board): + # 判断为空的情况 + if not board: + return [] + + m, n = len(board), len(board[0]) + d = ((1, 0), (-1, 0), (0, 1), (0, -1)) + + def dfs(x, y): + # 变换符号为'Y' + board[x][y] = 'Y' + # 对四个方向进行搜索 + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == 'O': + dfs(nx, ny) + + for i in range(m): + for j in range(n): + # 对四条边上的'O'进行深度优先搜索 + if i-1<0 or i+1==m or j-1<0 or j+1==n: + if board[i][j] == 'O': + dfs(i, j) + + # 再次遍历矩阵,将被包围的'O'改为'X',将'Y'改为原来的'O' + for i in range(m): + for j in range(n): + if board[i][j] == 'O': + board[i][j] = 'X' + if board[i][j] == 'Y': + board[i][j] = 'O' + + return board + + +# 广度优先搜索 +import collections +class Solution2(object): + def solve(self, board): + if not board: + return [] + + m, n = len(board), len(board[0]) + d = ((1, 0), (-1, 0), (0, 1), (0, -1)) + + for i in range(m): + for j in range(n): + if i-1<0 or i+1==m or j-1<0 or j+1==n: + if board[i][j] == 'O': + q = collections.deque() + q.appendleft((i, j)) + while q: + x, y = q.pop() + board[x][y] = 'Y' + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and board[nx][ny] == 'O': + q.appendleft((nx, ny)) + + for i in range(m): + for j in range(n): + if board[i][j] == 'O': + board[i][j] = 'X' + if board[i][j] == 'Y': + board[i][j] = 'O' + return board \ No newline at end of file diff --git "a/leetcode/131.\345\210\206\345\211\262\345\233\236\346\226\207\344\270\262.py" "b/leetcode_Python/131.\345\210\206\345\211\262\345\233\236\346\226\207\344\270\262.py" similarity index 97% rename from "leetcode/131.\345\210\206\345\211\262\345\233\236\346\226\207\344\270\262.py" rename to "leetcode_Python/131.\345\210\206\345\211\262\345\233\236\346\226\207\344\270\262.py" index 7b86af2..468a37f 100644 --- "a/leetcode/131.\345\210\206\345\211\262\345\233\236\346\226\207\344\270\262.py" +++ "b/leetcode_Python/131.\345\210\206\345\211\262\345\233\236\346\226\207\344\270\262.py" @@ -1,55 +1,55 @@ -class Solution(object): - def partition(self, s): - # 参数:字符串,输出数组 - def cut(s, output): - # 终止条件,字符串全部切割完毕,将输出数组添加到全局数组中,返回空结束递归 - if not s: - res.append(output) - return - # 遍历字符串从头开始的每个子串 - for i in range(1, len(s)+1): - # 若该子串为回文串 - if s[:i] == s[:i][::-1]: - # 则调用递归,字符串和输出数组动态更新,逐步产生结果,递归完成后回溯,继续搜索下一个结果 - cut(s[i:], output + [s[:i]]) - - res = [] - cut(s, []) - return res - - -class Solution2(object): - def partition(self, s): - # 字符串为空,返回包含一个空数组的数组 - if not s: - return [[]] - # 当前字符串的回文串结果数组 - res = [] - for i in range(len(s)): - temp = s[:i+1] - if temp == temp[::-1]: - # 遍历获取余下字符串的回文串结果数组 - for j in self.partition(s[i+1:]): - # 当前字符串的首个回文串添加到已有回文串数组中,构成新的回文串数组 - res.append([temp] + j) - # 返回当前字符串的回文串结果数组 - return res - - -class Solution3(object): - def __init__(self): - self.res = [] - self.output = [] - - def partition(self, s): - # 终止条件,字符串全部切割完毕,将输出数组添加到全局数组中,返回空结束递归 - if not s: - self.res.append(self.output) - return - for i in range(1, len(s)+1): - if s[:i] == s[:i][::-1]: - # 先更新输出数组,递归回溯后再弹出新值,还原输出数组,搜索下一种情况 - self.output.append(s[:i]) - self.partition(s[i:]) - self.output.pop() +class Solution(object): + def partition(self, s): + # 参数:字符串,输出数组 + def cut(s, output): + # 终止条件,字符串全部切割完毕,将输出数组添加到全局数组中,返回空结束递归 + if not s: + res.append(output) + return + # 遍历字符串从头开始的每个子串 + for i in range(1, len(s)+1): + # 若该子串为回文串 + if s[:i] == s[:i][::-1]: + # 则调用递归,字符串和输出数组动态更新,逐步产生结果,递归完成后回溯,继续搜索下一个结果 + cut(s[i:], output + [s[:i]]) + + res = [] + cut(s, []) + return res + + +class Solution2(object): + def partition(self, s): + # 字符串为空,返回包含一个空数组的数组 + if not s: + return [[]] + # 当前字符串的回文串结果数组 + res = [] + for i in range(len(s)): + temp = s[:i+1] + if temp == temp[::-1]: + # 遍历获取余下字符串的回文串结果数组 + for j in self.partition(s[i+1:]): + # 当前字符串的首个回文串添加到已有回文串数组中,构成新的回文串数组 + res.append([temp] + j) + # 返回当前字符串的回文串结果数组 + return res + + +class Solution3(object): + def __init__(self): + self.res = [] + self.output = [] + + def partition(self, s): + # 终止条件,字符串全部切割完毕,将输出数组添加到全局数组中,返回空结束递归 + if not s: + self.res.append(self.output) + return + for i in range(1, len(s)+1): + if s[:i] == s[:i][::-1]: + # 先更新输出数组,递归回溯后再弹出新值,还原输出数组,搜索下一种情况 + self.output.append(s[:i]) + self.partition(s[i:]) + self.output.pop() return self.res \ No newline at end of file diff --git "a/leetcode/133.\345\205\213\351\232\206\345\233\276.py" "b/leetcode_Python/133.\345\205\213\351\232\206\345\233\276.py" similarity index 97% rename from "leetcode/133.\345\205\213\351\232\206\345\233\276.py" rename to "leetcode_Python/133.\345\205\213\351\232\206\345\233\276.py" index 5e830ce..58bd308 100644 --- "a/leetcode/133.\345\205\213\351\232\206\345\233\276.py" +++ "b/leetcode_Python/133.\345\205\213\351\232\206\345\233\276.py" @@ -1,52 +1,52 @@ -class Solution(object): - def cloneGraph(self, node): - return copy.deepcopy(node) - - -# 广度优先搜索 -class Solution2(object): - def cloneGraph(self, node): - d = {} - # 拷贝第一个新结点到字典 - d[node] = Node(node.val, []) - # 第一个旧结点添加到队列 - queue = [node] - while queue: - cur_node = queue.pop(0) - # 遍历当前结点的邻居结点 - for nodes in cur_node.neighbors: - if nodes not in d: - # 拷贝新邻居结点到字典 - d[nodes] = Node(nodes.val, []) - # 添加旧邻居结点到队列 - queue.append(nodes) - # 拷贝新结点的邻居结点 - d[cur_node].neighbors.append(d[nodes]) - # 返回第一个新结点 - return d[node] - - -# 深度优先搜索 -class Solution3(object): - def cloneGraph(self, node): - # 方法作用:传入结点,拷贝结点值,拷贝邻居,返回结点 - def dfs(node): - # 终止条件 - if not node: - return - # 拷贝新结点并添加到字典中 - new_node = Node(node.val, []) - d[node] = new_node - # 遍历旧结点的邻居结点 - for i in node.neighbors: - # 若邻居结点不在字典中,则递归拷贝邻居结点 - if i not in d: - new_node.neighbors.append(dfs(i)) - # 否则直接添加邻居结点 - else: - new_node.neighbors.append(d[i]) - # 返回新结点 - return new_node - - d = {} +class Solution(object): + def cloneGraph(self, node): + return copy.deepcopy(node) + + +# 广度优先搜索 +class Solution2(object): + def cloneGraph(self, node): + d = {} + # 拷贝第一个新结点到字典 + d[node] = Node(node.val, []) + # 第一个旧结点添加到队列 + queue = [node] + while queue: + cur_node = queue.pop(0) + # 遍历当前结点的邻居结点 + for nodes in cur_node.neighbors: + if nodes not in d: + # 拷贝新邻居结点到字典 + d[nodes] = Node(nodes.val, []) + # 添加旧邻居结点到队列 + queue.append(nodes) + # 拷贝新结点的邻居结点 + d[cur_node].neighbors.append(d[nodes]) + # 返回第一个新结点 + return d[node] + + +# 深度优先搜索 +class Solution3(object): + def cloneGraph(self, node): + # 方法作用:传入结点,拷贝结点值,拷贝邻居,返回结点 + def dfs(node): + # 终止条件 + if not node: + return + # 拷贝新结点并添加到字典中 + new_node = Node(node.val, []) + d[node] = new_node + # 遍历旧结点的邻居结点 + for i in node.neighbors: + # 若邻居结点不在字典中,则递归拷贝邻居结点 + if i not in d: + new_node.neighbors.append(dfs(i)) + # 否则直接添加邻居结点 + else: + new_node.neighbors.append(d[i]) + # 返回新结点 + return new_node + + d = {} return dfs(node) \ No newline at end of file diff --git "a/leetcode/134.\345\212\240\346\262\271\347\253\231.py" "b/leetcode_Python/134.\345\212\240\346\262\271\347\253\231.py" similarity index 97% rename from "leetcode/134.\345\212\240\346\262\271\347\253\231.py" rename to "leetcode_Python/134.\345\212\240\346\262\271\347\253\231.py" index 79ce843..0099e65 100644 --- "a/leetcode/134.\345\212\240\346\262\271\347\253\231.py" +++ "b/leetcode_Python/134.\345\212\240\346\262\271\347\253\231.py" @@ -1,18 +1,18 @@ -# 拼接数组代表环形,遍历每个站点分别作为起始点。判断当前油量是否不小于到下一站的油耗,若不小于则计算到下一站补充后的总油量, -# 若小于则退出判断下一站点。若最终可绕环则返回该站点 -class Solution(object): - def canCompleteCircuit(self, gas, cost): - n = len(gas) - gas += gas - cost += cost - for i in range(n): - tank, count = gas[i], 0 - for j in range(i, i+n): - if tank >= cost[j]: - tank = tank - cost[j] + gas[j+1] - count += 1 - else: - break - if count == n: - return i +# 拼接数组代表环形,遍历每个站点分别作为起始点。判断当前油量是否不小于到下一站的油耗,若不小于则计算到下一站补充后的总油量, +# 若小于则退出判断下一站点。若最终可绕环则返回该站点 +class Solution(object): + def canCompleteCircuit(self, gas, cost): + n = len(gas) + gas += gas + cost += cost + for i in range(n): + tank, count = gas[i], 0 + for j in range(i, i+n): + if tank >= cost[j]: + tank = tank - cost[j] + gas[j+1] + count += 1 + else: + break + if count == n: + return i return -1 \ No newline at end of file diff --git "a/leetcode/136.\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" "b/leetcode_Python/136.\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" similarity index 97% rename from "leetcode/136.\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" rename to "leetcode_Python/136.\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" index affbe6f..5ca5bc4 100644 --- "a/leetcode/136.\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" +++ "b/leetcode_Python/136.\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" @@ -1,5 +1,5 @@ -class Solution(object): - def singleNumber(self, nums): - d = collections.Counter(nums) - res = [k for k in d if d[k]==1] +class Solution(object): + def singleNumber(self, nums): + d = collections.Counter(nums) + res = [k for k in d if d[k]==1] return res[0] \ No newline at end of file diff --git "a/leetcode/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" "b/leetcode_Python/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" rename to "leetcode_Python/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" index ef8bde0..0021af8 100644 --- "a/leetcode/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" +++ "b/leetcode_Python/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250.py" @@ -1,46 +1,46 @@ -# 方法一:在原链表上复制结点,新结点在旧结点之后 -class Solution(object): - def copyRandomList(self, head): - # 复制结点 - h = head - while h: - new = RandomListNode(h.label) - new.next = h.next - h.next = new - h = new.next - # 复制随机指针 - h = head - while h: - if h.random: - h.next.random = h.random.next - h = h.next.next - # 获取新链表 - res = copy = RandomListNode(0) - while head: - copy.next = head.next - copy = copy.next - head.next = head.next.next - head = head.next - return res.next - -# 方法二:使用字典复制结点,key:旧结点,value:新结点 -class Solution(object): - def copyRandomList(self, head): - if not head: - return - d = dict() - # 复制结点 - h = head - while h: - d[h] = RandomListNode(h.label) - h = h.next - # 随机指针可能为空 - d[None] = None - # 复制随机指针 - h = head - while h: - d[h].next = d[h.next] - d[h].random = d[h.random] - h = h.next - # 返回新链表 +# 方法一:在原链表上复制结点,新结点在旧结点之后 +class Solution(object): + def copyRandomList(self, head): + # 复制结点 + h = head + while h: + new = RandomListNode(h.label) + new.next = h.next + h.next = new + h = new.next + # 复制随机指针 + h = head + while h: + if h.random: + h.next.random = h.random.next + h = h.next.next + # 获取新链表 + res = copy = RandomListNode(0) + while head: + copy.next = head.next + copy = copy.next + head.next = head.next.next + head = head.next + return res.next + +# 方法二:使用字典复制结点,key:旧结点,value:新结点 +class Solution(object): + def copyRandomList(self, head): + if not head: + return + d = dict() + # 复制结点 + h = head + while h: + d[h] = RandomListNode(h.label) + h = h.next + # 随机指针可能为空 + d[None] = None + # 复制随机指针 + h = head + while h: + d[h].next = d[h.next] + d[h].random = d[h.random] + h = h.next + # 返回新链表 return d[head] \ No newline at end of file diff --git "a/leetcode/141.\347\216\257\345\275\242\351\223\276\350\241\250.py" "b/leetcode_Python/141.\347\216\257\345\275\242\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/141.\347\216\257\345\275\242\351\223\276\350\241\250.py" rename to "leetcode_Python/141.\347\216\257\345\275\242\351\223\276\350\241\250.py" index 34a9a86..a6725db 100644 --- "a/leetcode/141.\347\216\257\345\275\242\351\223\276\350\241\250.py" +++ "b/leetcode_Python/141.\347\216\257\345\275\242\351\223\276\350\241\250.py" @@ -1,21 +1,21 @@ -# 方法一:使用快慢指针,若指针相遇,则有环 -class Solution(object): - def hasCycle(self, head): - fast = slow = head - while fast and fast.next: - slow = slow.next - fast = fast.next.next - if slow == fast: - return True - return False - -# 方法二:使用字典存放访问过的结点 -class Solution(object): - def hasCycle(self, head): - d = dict() - while head: - if head in d: - return True - d[head] = 1 - head = head.next +# 方法一:使用快慢指针,若指针相遇,则有环 +class Solution(object): + def hasCycle(self, head): + fast = slow = head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + return True + return False + +# 方法二:使用字典存放访问过的结点 +class Solution(object): + def hasCycle(self, head): + d = dict() + while head: + if head in d: + return True + d[head] = 1 + head = head.next return False \ No newline at end of file diff --git "a/leetcode/142.\347\216\257\345\275\242\351\223\276\350\241\250II.py" "b/leetcode_Python/142.\347\216\257\345\275\242\351\223\276\350\241\250II.py" similarity index 97% rename from "leetcode/142.\347\216\257\345\275\242\351\223\276\350\241\250II.py" rename to "leetcode_Python/142.\347\216\257\345\275\242\351\223\276\350\241\250II.py" index 2b3faf6..f127b3f 100644 --- "a/leetcode/142.\347\216\257\345\275\242\351\223\276\350\241\250II.py" +++ "b/leetcode_Python/142.\347\216\257\345\275\242\351\223\276\350\241\250II.py" @@ -1,30 +1,30 @@ -# 方法一:用字典存放结点,遍历链表,若结点出现在字典中则为入环第一个结点 -class Solution(object): - def detectCycle(self, head): - d = dict() - while head: - if head in d: - return head - d[head] = 1 - head = head.next - return - -# 方法二 -class Solution(object): - def detectCycle(self, head): - # 用快慢指针移动,由于步数差一倍,若两指针相遇,则有环 - fast = slow = head - while fast and fast.next: - slow = slow.next - fast = fast.next.next - if slow == fast: - break - else: - return - # 假设head到环的距离为A,快慢指针相遇时慢指针离入环结点走的距离为B,假设环的长度为L。 - # 则慢指针共走了A+B,快指针走了2A+2B,由于快指针比慢指针多了一圈,可表示为A+B,则2A+2B=L+A+B,即L=A+B - # 故head指针和slow指针到入环结点的距离相等 - while head != slow: - slow = slow.next - head = head.next +# 方法一:用字典存放结点,遍历链表,若结点出现在字典中则为入环第一个结点 +class Solution(object): + def detectCycle(self, head): + d = dict() + while head: + if head in d: + return head + d[head] = 1 + head = head.next + return + +# 方法二 +class Solution(object): + def detectCycle(self, head): + # 用快慢指针移动,由于步数差一倍,若两指针相遇,则有环 + fast = slow = head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + break + else: + return + # 假设head到环的距离为A,快慢指针相遇时慢指针离入环结点走的距离为B,假设环的长度为L。 + # 则慢指针共走了A+B,快指针走了2A+2B,由于快指针比慢指针多了一圈,可表示为A+B,则2A+2B=L+A+B,即L=A+B + # 故head指针和slow指针到入环结点的距离相等 + while head != slow: + slow = slow.next + head = head.next return head \ No newline at end of file diff --git "a/leetcode/143.\351\207\215\346\216\222\351\223\276\350\241\250.py" "b/leetcode_Python/143.\351\207\215\346\216\222\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/143.\351\207\215\346\216\222\351\223\276\350\241\250.py" rename to "leetcode_Python/143.\351\207\215\346\216\222\351\223\276\350\241\250.py" index 0a1840f..8a2bad9 100644 --- "a/leetcode/143.\351\207\215\346\216\222\351\223\276\350\241\250.py" +++ "b/leetcode_Python/143.\351\207\215\346\216\222\351\223\276\350\241\250.py" @@ -1,31 +1,31 @@ -class Solution(object): - def reorderList(self, head): - if not head or not head.next or not head.next.next: - return - - # 快慢指针,获取后半段链表,并将前半段尾指针指向空 - fast, slow = head, head - s_pre = None - while fast and fast.next: - s_pre = slow - slow = slow.next - fast = fast.next.next - s_pre.next = None - - # 反转链表,最终头指针为pre - pre = None - while slow: - lat = slow.next - slow.next = pre - pre = slow - slow = lat - - # 两个链表结点值交替添加 - cur = head - while cur.next: - tmp = cur.next - cur.next = pre - pre = pre.next - cur.next.next = tmp - cur = tmp +class Solution(object): + def reorderList(self, head): + if not head or not head.next or not head.next.next: + return + + # 快慢指针,获取后半段链表,并将前半段尾指针指向空 + fast, slow = head, head + s_pre = None + while fast and fast.next: + s_pre = slow + slow = slow.next + fast = fast.next.next + s_pre.next = None + + # 反转链表,最终头指针为pre + pre = None + while slow: + lat = slow.next + slow.next = pre + pre = slow + slow = lat + + # 两个链表结点值交替添加 + cur = head + while cur.next: + tmp = cur.next + cur.next = pre + pre = pre.next + cur.next.next = tmp + cur = tmp cur.next = pre \ No newline at end of file diff --git "a/leetcode/144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" "b/leetcode_Python/144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" similarity index 97% rename from "leetcode/144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" rename to "leetcode_Python/144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" index 39e8e71..5ad35c0 100644 --- "a/leetcode/144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" +++ "b/leetcode_Python/144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" @@ -1,10 +1,10 @@ -# 根左右 -class Solution(object): - def __init__(self): - self.res = [] - def preorderTraversal(self, root): - if root != None: - self.res.append(root.val) - self.preorderTraversal(root.left) - self.preorderTraversal(root.right) +# 根左右 +class Solution(object): + def __init__(self): + self.res = [] + def preorderTraversal(self, root): + if root != None: + self.res.append(root.val) + self.preorderTraversal(root.left) + self.preorderTraversal(root.right) return self.res \ No newline at end of file diff --git "a/leetcode/145.\344\272\214\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" "b/leetcode_Python/145.\344\272\214\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" similarity index 97% rename from "leetcode/145.\344\272\214\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" rename to "leetcode_Python/145.\344\272\214\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" index aec3e82..194cc59 100644 --- "a/leetcode/145.\344\272\214\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" +++ "b/leetcode_Python/145.\344\272\214\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" @@ -1,10 +1,10 @@ -# 左右根 -class Solution(object): - def __init__(self): - self.res = [] - def postorderTraversal(self, root): - if root != None: - self.postorderTraversal(root.left) - self.postorderTraversal(root.right) - self.res.append(root.val) +# 左右根 +class Solution(object): + def __init__(self): + self.res = [] + def postorderTraversal(self, root): + if root != None: + self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + self.res.append(root.val) return self.res \ No newline at end of file diff --git "a/leetcode/147.\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" "b/leetcode_Python/147.\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" similarity index 97% rename from "leetcode/147.\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" rename to "leetcode_Python/147.\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" index cc23d99..c7b0eb7 100644 --- "a/leetcode/147.\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" +++ "b/leetcode_Python/147.\345\257\271\351\223\276\350\241\250\350\277\233\350\241\214\346\217\222\345\205\245\346\216\222\345\272\217.py" @@ -1,27 +1,27 @@ -class Solution(object): - def insertionSortList(self, head): - if not head or not head.next: - return head - - h = ListNode(-1) - h.next = head - pre = h - cur = head - while cur: - lat = cur.next - # 下一个结点值比当前小 - if lat and lat.val < cur.val: - # 从头开始遍历,找到第一个比待插入结点大的结点 - while pre.next and pre.next.val < lat.val: - pre = pre.next - # 将结点插入到它的前面 - big = pre.next - pre.next = lat - cur.next = lat.next - lat.next = big - # 指针再次指向头结点,便于下个结点排序遍历 - pre = h - else: - cur = lat - +class Solution(object): + def insertionSortList(self, head): + if not head or not head.next: + return head + + h = ListNode(-1) + h.next = head + pre = h + cur = head + while cur: + lat = cur.next + # 下一个结点值比当前小 + if lat and lat.val < cur.val: + # 从头开始遍历,找到第一个比待插入结点大的结点 + while pre.next and pre.next.val < lat.val: + pre = pre.next + # 将结点插入到它的前面 + big = pre.next + pre.next = lat + cur.next = lat.next + lat.next = big + # 指针再次指向头结点,便于下个结点排序遍历 + pre = h + else: + cur = lat + return h.next \ No newline at end of file diff --git "a/leetcode/148.\346\216\222\345\272\217\351\223\276\350\241\250.py" "b/leetcode_Python/148.\346\216\222\345\272\217\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/148.\346\216\222\345\272\217\351\223\276\350\241\250.py" rename to "leetcode_Python/148.\346\216\222\345\272\217\351\223\276\350\241\250.py" index 0615648..558c108 100644 --- "a/leetcode/148.\346\216\222\345\272\217\351\223\276\350\241\250.py" +++ "b/leetcode_Python/148.\346\216\222\345\272\217\351\223\276\350\241\250.py" @@ -1,16 +1,16 @@ -# 将链表的值存放在数组中,数组排序后,再将值转化为链表 -class Solution(object): - def sortList(self, head): - if not head: - return - res = [] - while head: - res.append(head.val) - head = head.next - res.sort() - head = ListNode(res[0]) - tmp = head - for node in res[1:]: - head.next = ListNode(node) - head = head.next +# 将链表的值存放在数组中,数组排序后,再将值转化为链表 +class Solution(object): + def sortList(self, head): + if not head: + return + res = [] + while head: + res.append(head.val) + head = head.next + res.sort() + head = ListNode(res[0]) + tmp = head + for node in res[1:]: + head.next = ListNode(node) + head = head.next return tmp \ No newline at end of file diff --git "a/leetcode/151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.py" "b/leetcode_Python/151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.py" similarity index 97% rename from "leetcode/151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.py" rename to "leetcode_Python/151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.py" index 17e58a8..6816a7f 100644 --- "a/leetcode/151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.py" +++ "b/leetcode_Python/151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.py" @@ -1,4 +1,4 @@ -# 按空格切分单词再反转 -class Solution(object): - def reverseWords(self, s): +# 按空格切分单词再反转 +class Solution(object): + def reverseWords(self, s): return ' '.join(s.split()[::-1]) \ No newline at end of file diff --git "a/leetcode/155.\346\234\200\345\260\217\346\240\210.py" "b/leetcode_Python/155.\346\234\200\345\260\217\346\240\210.py" similarity index 94% rename from "leetcode/155.\346\234\200\345\260\217\346\240\210.py" rename to "leetcode_Python/155.\346\234\200\345\260\217\346\240\210.py" index 58084bd..2484cb5 100644 --- "a/leetcode/155.\346\234\200\345\260\217\346\240\210.py" +++ "b/leetcode_Python/155.\346\234\200\345\260\217\346\240\210.py" @@ -1,16 +1,16 @@ -class MinStack(object): - - def __init__(self): - self.stack = [] - - def push(self, x): - self.stack.append(x) - - def pop(self): - self.stack.pop() - - def top(self): - return self.stack[-1] - - def getMin(self): +class MinStack(object): + + def __init__(self): + self.stack = [] + + def push(self, x): + self.stack.append(x) + + def pop(self): + self.stack.pop() + + def top(self): + return self.stack[-1] + + def getMin(self): return min(self.stack) \ No newline at end of file diff --git "a/leetcode/160.\347\233\270\344\272\244\351\223\276\350\241\250.py" "b/leetcode_Python/160.\347\233\270\344\272\244\351\223\276\350\241\250.py" similarity index 97% rename from "leetcode/160.\347\233\270\344\272\244\351\223\276\350\241\250.py" rename to "leetcode_Python/160.\347\233\270\344\272\244\351\223\276\350\241\250.py" index 2a74d7b..3e7e006 100644 --- "a/leetcode/160.\347\233\270\344\272\244\351\223\276\350\241\250.py" +++ "b/leetcode_Python/160.\347\233\270\344\272\244\351\223\276\350\241\250.py" @@ -1,52 +1,52 @@ -# 方法一:先将链表A的结点存放在字典中,遍历链表B,如果该结点已在字典中,则为相交起始结点 -class Solution(object): - def getIntersectionNode(self, headA, headB): - d = dict() - while headA: - d[headA] = 1 - headA = headA.next - while headB: - if headB in d: - return headB - headB = headB.next - return None - -# 方法二:遍历并得到两个链表的长度差值,较长者先移动使得剩余长度一致,再判断两个链表的结点是否相同,相同则为相交起始结点 -class Solution(object): - def getIntersectionNode(self, headA, headB): - def getLength(head): - length = 0 - while head: - length += 1 - head = head.next - return length - - a = getLength(headA) - b = getLength(headB) - if a>b: - for _ in range(a-b): - headA = headA.next - else: - for _ in range(b-a): - headB = headB.next - - while headA != headB: - headA, headB = headA.next, headB.next - return headA - -# 方法三:使用两个指针都遍历两个链表,由于走的长度一致,最终会在某点相遇,该点就是相交起始结点 -class Solution(object): - def getIntersectionNode(self, headA, headB): - if not headA or not headB: - return None - - A, B = headA, headB - while A and B and A!=B: - A, B = A.next, B.next - if A==B: - return A - if not A: - A = headB - if not B: - B = headA +# 方法一:先将链表A的结点存放在字典中,遍历链表B,如果该结点已在字典中,则为相交起始结点 +class Solution(object): + def getIntersectionNode(self, headA, headB): + d = dict() + while headA: + d[headA] = 1 + headA = headA.next + while headB: + if headB in d: + return headB + headB = headB.next + return None + +# 方法二:遍历并得到两个链表的长度差值,较长者先移动使得剩余长度一致,再判断两个链表的结点是否相同,相同则为相交起始结点 +class Solution(object): + def getIntersectionNode(self, headA, headB): + def getLength(head): + length = 0 + while head: + length += 1 + head = head.next + return length + + a = getLength(headA) + b = getLength(headB) + if a>b: + for _ in range(a-b): + headA = headA.next + else: + for _ in range(b-a): + headB = headB.next + + while headA != headB: + headA, headB = headA.next, headB.next + return headA + +# 方法三:使用两个指针都遍历两个链表,由于走的长度一致,最终会在某点相遇,该点就是相交起始结点 +class Solution(object): + def getIntersectionNode(self, headA, headB): + if not headA or not headB: + return None + + A, B = headA, headB + while A and B and A!=B: + A, B = A.next, B.next + if A==B: + return A + if not A: + A = headB + if not B: + B = headA return A \ No newline at end of file diff --git "a/leetcode/167.\344\270\244\346\225\260\344\271\213\345\222\214II-\350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.py" "b/leetcode_Python/167.\344\270\244\346\225\260\344\271\213\345\222\214II-\350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.py" similarity index 97% rename from "leetcode/167.\344\270\244\346\225\260\344\271\213\345\222\214II-\350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.py" rename to "leetcode_Python/167.\344\270\244\346\225\260\344\271\213\345\222\214II-\350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.py" index 6358ad0..09215f7 100644 --- "a/leetcode/167.\344\270\244\346\225\260\344\271\213\345\222\214II-\350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.py" +++ "b/leetcode_Python/167.\344\270\244\346\225\260\344\271\213\345\222\214II-\350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.py" @@ -1,9 +1,9 @@ -# 用字典存储遍历过的值和索引 -class Solution(object): - def twoSum(self, numbers, target): - d = dict() - for index, value in enumerate(numbers): - sub = target - value - if sub in d.keys(): - return [d[sub]+1, index+1] +# 用字典存储遍历过的值和索引 +class Solution(object): + def twoSum(self, numbers, target): + d = dict() + for index, value in enumerate(numbers): + sub = target - value + if sub in d.keys(): + return [d[sub]+1, index+1] d[value] = index \ No newline at end of file diff --git "a/leetcode/169.\346\261\202\344\274\227\346\225\260.py" "b/leetcode_Python/169.\346\261\202\344\274\227\346\225\260.py" similarity index 97% rename from "leetcode/169.\346\261\202\344\274\227\346\225\260.py" rename to "leetcode_Python/169.\346\261\202\344\274\227\346\225\260.py" index ad57e82..e4e69ea 100644 --- "a/leetcode/169.\346\261\202\344\274\227\346\225\260.py" +++ "b/leetcode_Python/169.\346\261\202\344\274\227\346\225\260.py" @@ -1,7 +1,7 @@ -# 用集合存放去重后的数,再统计每个数出现次数 -class Solution(object): - def majorityElement(self, nums): - s = set(nums) - for i in s: - if nums.count(i) > len(nums)/2: +# 用集合存放去重后的数,再统计每个数出现次数 +class Solution(object): + def majorityElement(self, nums): + s = set(nums) + for i in s: + if nums.count(i) > len(nums)/2: return i \ No newline at end of file diff --git "a/leetcode/171.Excel\350\241\250\345\210\227\345\272\217\345\217\267.py" "b/leetcode_Python/171.Excel\350\241\250\345\210\227\345\272\217\345\217\267.py" similarity index 96% rename from "leetcode/171.Excel\350\241\250\345\210\227\345\272\217\345\217\267.py" rename to "leetcode_Python/171.Excel\350\241\250\345\210\227\345\272\217\345\217\267.py" index 7da2300..eb35d83 100644 --- "a/leetcode/171.Excel\350\241\250\345\210\227\345\272\217\345\217\267.py" +++ "b/leetcode_Python/171.Excel\350\241\250\345\210\227\345\272\217\345\217\267.py" @@ -1,17 +1,17 @@ -# 26进制转10进制。正序 -class Solution(object): - def titleToNumber(self, s): - res = 0 - for i in range(len(s)): - res += (26**(len(s)-i-1)) * (ord(s[i])-ord('A')+1) - return int(res) - -# 逆序 -class Solution(object): - def titleToNumber(self, s): - S = list(s) - S.reverse() - res = 0 - for i, v in enumerate(S): - res += (26**i) * (ord(v)-ord('A')+1) +# 26进制转10进制。正序 +class Solution(object): + def titleToNumber(self, s): + res = 0 + for i in range(len(s)): + res += (26**(len(s)-i-1)) * (ord(s[i])-ord('A')+1) + return int(res) + +# 逆序 +class Solution(object): + def titleToNumber(self, s): + S = list(s) + S.reverse() + res = 0 + for i, v in enumerate(S): + res += (26**i) * (ord(v)-ord('A')+1) return res \ No newline at end of file diff --git "a/leetcode/172.\351\230\266\344\271\230\345\220\216\347\232\204\351\233\266.py" "b/leetcode_Python/172.\351\230\266\344\271\230\345\220\216\347\232\204\351\233\266.py" similarity index 97% rename from "leetcode/172.\351\230\266\344\271\230\345\220\216\347\232\204\351\233\266.py" rename to "leetcode_Python/172.\351\230\266\344\271\230\345\220\216\347\232\204\351\233\266.py" index 8104a47..d1f0baa 100644 --- "a/leetcode/172.\351\230\266\344\271\230\345\220\216\347\232\204\351\233\266.py" +++ "b/leetcode_Python/172.\351\230\266\344\271\230\345\220\216\347\232\204\351\233\266.py" @@ -1,8 +1,8 @@ -# 找规律,将阶乘中的数分解成因子,有1个5则可以和前面分解出来的2搭配 2*5=10,则末尾就会有1个0 -class Solution(object): - def trailingZeroes(self, n): - res = 0 - while n > 0: - n /= 5 - res += n +# 找规律,将阶乘中的数分解成因子,有1个5则可以和前面分解出来的2搭配 2*5=10,则末尾就会有1个0 +class Solution(object): + def trailingZeroes(self, n): + res = 0 + while n > 0: + n /= 5 + res += n return res \ No newline at end of file diff --git "a/leetcode/173.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" "b/leetcode_Python/173.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" similarity index 96% rename from "leetcode/173.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" rename to "leetcode_Python/173.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" index ef8c37b..e38c0a0 100644 --- "a/leetcode/173.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" +++ "b/leetcode_Python/173.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\277\255\344\273\243\345\231\250.py" @@ -1,18 +1,18 @@ -# 使用中序遍历的到的有序数组 -class BSTIterator(object): - def __init__(self, root): - self.root = root - self.res = [] - self.inorder(root) - - def hasNext(self): - return self.res != [] - - def next(self): - return self.res.pop(0) - - def inorder(self, root): - if root: - self.inorder(root.left) - self.res.append(root.val) +# 使用中序遍历的到的有序数组 +class BSTIterator(object): + def __init__(self, root): + self.root = root + self.res = [] + self.inorder(root) + + def hasNext(self): + return self.res != [] + + def next(self): + return self.res.pop(0) + + def inorder(self, root): + if root: + self.inorder(root.left) + self.res.append(root.val) self.inorder(root.right) \ No newline at end of file diff --git "a/leetcode/189.\346\227\213\350\275\254\346\225\260\347\273\204.py" "b/leetcode_Python/189.\346\227\213\350\275\254\346\225\260\347\273\204.py" similarity index 97% rename from "leetcode/189.\346\227\213\350\275\254\346\225\260\347\273\204.py" rename to "leetcode_Python/189.\346\227\213\350\275\254\346\225\260\347\273\204.py" index 892b7fb..5acbcb1 100644 --- "a/leetcode/189.\346\227\213\350\275\254\346\225\260\347\273\204.py" +++ "b/leetcode_Python/189.\346\227\213\350\275\254\346\225\260\347\273\204.py" @@ -1,12 +1,12 @@ -# 方法一:每一次旋转将最后一个元素放到首位 -class Solution(object): - def rotate(self, nums, k): - for _ in range(k): - num = nums.pop() - nums.insert(0, num) - -# 方法二:数组局部交换位置 -class Solution(object): - def rotate(self, nums, k): - k %= len(nums) +# 方法一:每一次旋转将最后一个元素放到首位 +class Solution(object): + def rotate(self, nums, k): + for _ in range(k): + num = nums.pop() + nums.insert(0, num) + +# 方法二:数组局部交换位置 +class Solution(object): + def rotate(self, nums, k): + k %= len(nums) nums[:] = nums[-k:] + nums[:-k] \ No newline at end of file diff --git "a/leetcode/190.\351\242\240\345\200\222\344\272\214\350\277\233\345\210\266\344\275\215.py" "b/leetcode_Python/190.\351\242\240\345\200\222\344\272\214\350\277\233\345\210\266\344\275\215.py" similarity index 97% rename from "leetcode/190.\351\242\240\345\200\222\344\272\214\350\277\233\345\210\266\344\275\215.py" rename to "leetcode_Python/190.\351\242\240\345\200\222\344\272\214\350\277\233\345\210\266\344\275\215.py" index ad7696b..48e0783 100644 --- "a/leetcode/190.\351\242\240\345\200\222\344\272\214\350\277\233\345\210\266\344\275\215.py" +++ "b/leetcode_Python/190.\351\242\240\345\200\222\344\272\214\350\277\233\345\210\266\344\275\215.py" @@ -1,13 +1,13 @@ -# 方法一:将无符号整数转为二进制,用0补满32位,反转后将二进制格式转为十进制 -class Solution: - def reverseBits(self, n): - return int(bin(n)[2:].zfill(32)[::-1], 2) - -# 方法二:位运算,res每次左移加上n的最后一位,然后n右移去掉最后一位 -class Solution: - def reverseBits(self, n): - res = 0 - for _ in range(32): - res = (res<<1) + n%2 - n >>= 1 +# 方法一:将无符号整数转为二进制,用0补满32位,反转后将二进制格式转为十进制 +class Solution: + def reverseBits(self, n): + return int(bin(n)[2:].zfill(32)[::-1], 2) + +# 方法二:位运算,res每次左移加上n的最后一位,然后n右移去掉最后一位 +class Solution: + def reverseBits(self, n): + res = 0 + for _ in range(32): + res = (res<<1) + n%2 + n >>= 1 return res \ No newline at end of file diff --git "a/leetcode/191.\344\275\2151\347\232\204\344\270\252\346\225\260.py" "b/leetcode_Python/191.\344\275\2151\347\232\204\344\270\252\346\225\260.py" similarity index 98% rename from "leetcode/191.\344\275\2151\347\232\204\344\270\252\346\225\260.py" rename to "leetcode_Python/191.\344\275\2151\347\232\204\344\270\252\346\225\260.py" index e3fb580..29fbdc4 100644 --- "a/leetcode/191.\344\275\2151\347\232\204\344\270\252\346\225\260.py" +++ "b/leetcode_Python/191.\344\275\2151\347\232\204\344\270\252\346\225\260.py" @@ -1,4 +1,4 @@ -# 输入是一个无符号整数,要先转化为二进制形式,再转为字符串形式统计1的个数 -class Solution(object): - def hammingWeight(self, n): +# 输入是一个无符号整数,要先转化为二进制形式,再转为字符串形式统计1的个数 +class Solution(object): + def hammingWeight(self, n): return bin(n).count('1') \ No newline at end of file diff --git "a/leetcode/197.\346\234\200\345\244\247\346\225\260.py" "b/leetcode_Python/197.\346\234\200\345\244\247\346\225\260.py" similarity index 98% rename from "leetcode/197.\346\234\200\345\244\247\346\225\260.py" rename to "leetcode_Python/197.\346\234\200\345\244\247\346\225\260.py" index 9e032f4..22fc282 100644 --- "a/leetcode/197.\346\234\200\345\244\247\346\225\260.py" +++ "b/leetcode_Python/197.\346\234\200\345\244\247\346\225\260.py" @@ -1,7 +1,7 @@ -class Solution(object): - def largestNumber(self, nums): - nums = map(str, nums) - # 两两相加比较,大于则交换位置 - nums.sort(cmp = lambda x, y: cmp(y+x, x+y)) - # 结果需要先去除最左边的0 +class Solution(object): + def largestNumber(self, nums): + nums = map(str, nums) + # 两两相加比较,大于则交换位置 + nums.sort(cmp = lambda x, y: cmp(y+x, x+y)) + # 结果需要先去除最左边的0 return ''.join(nums).lstrip('0') if ''.join(nums).lstrip('0') else '0' \ No newline at end of file diff --git "a/leetcode/198.\346\211\223\345\256\266\345\212\253\350\210\215.py" "b/leetcode_Python/198.\346\211\223\345\256\266\345\212\253\350\210\215.py" similarity index 97% rename from "leetcode/198.\346\211\223\345\256\266\345\212\253\350\210\215.py" rename to "leetcode_Python/198.\346\211\223\345\256\266\345\212\253\350\210\215.py" index 3ab6e14..c39b896 100644 --- "a/leetcode/198.\346\211\223\345\256\266\345\212\253\350\210\215.py" +++ "b/leetcode_Python/198.\346\211\223\345\256\266\345\212\253\350\210\215.py" @@ -1,13 +1,13 @@ -# 动态规划,求出打劫到每间房屋时能偷窃到的最高金额 -class Solution(object): - def rob(self, nums): - n = len(nums) - if n==0: - return 0 - elif n==1 or n==2: - return max(nums) - dp = [0] * n - dp[0], dp[1] = nums[0], max(nums[0], nums[1]) - for i in range(2, n): - dp[i] = max(dp[i-2] + nums[i], dp[i-1]) +# 动态规划,求出打劫到每间房屋时能偷窃到的最高金额 +class Solution(object): + def rob(self, nums): + n = len(nums) + if n==0: + return 0 + elif n==1 or n==2: + return max(nums) + dp = [0] * n + dp[0], dp[1] = nums[0], max(nums[0], nums[1]) + for i in range(2, n): + dp[i] = max(dp[i-2] + nums[i], dp[i-1]) return dp[-1] \ No newline at end of file diff --git "a/leetcode/199.\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276.py" "b/leetcode_Python/199.\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276.py" similarity index 97% rename from "leetcode/199.\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276.py" rename to "leetcode_Python/199.\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276.py" index d56249c..c9ddf51 100644 --- "a/leetcode/199.\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276.py" +++ "b/leetcode_Python/199.\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276.py" @@ -1,16 +1,16 @@ -# 层次遍历,添加每一层的最后一个值 -class Solution(object): - def rightSideView(self, root): - if not root: - return [] - res, cur_level, next_level, cur_val = [], [root], [], [] - while cur_level: - for node in cur_level: - cur_val.append(node.val) - if node.left: - next_level.append(node.left) - if node.right: - next_level.append(node.right) - res.append(cur_val[-1]) - cur_level, next_level, cur_val = next_level, [], [] +# 层次遍历,添加每一层的最后一个值 +class Solution(object): + def rightSideView(self, root): + if not root: + return [] + res, cur_level, next_level, cur_val = [], [root], [], [] + while cur_level: + for node in cur_level: + cur_val.append(node.val) + if node.left: + next_level.append(node.left) + if node.right: + next_level.append(node.right) + res.append(cur_val[-1]) + cur_level, next_level, cur_val = next_level, [], [] return res \ No newline at end of file diff --git "a/leetcode/200.\345\262\233\345\261\277\346\225\260\351\207\217.py" "b/leetcode_Python/200.\345\262\233\345\261\277\346\225\260\351\207\217.py" similarity index 96% rename from "leetcode/200.\345\262\233\345\261\277\346\225\260\351\207\217.py" rename to "leetcode_Python/200.\345\262\233\345\261\277\346\225\260\351\207\217.py" index d35b4ee..fae7d8c 100644 --- "a/leetcode/200.\345\262\233\345\261\277\346\225\260\351\207\217.py" +++ "b/leetcode_Python/200.\345\262\233\345\261\277\346\225\260\351\207\217.py" @@ -1,130 +1,130 @@ -# 深度优先搜索。原数组修改标志 -class Solution(object): - def numIslands(self, grid): - if not grid: - return 0 - - m, n = len(grid), len(grid[0]) - d = ((1, 0), (-1, 0), (0, 1), (0, -1)) - - def dfs(x, y): - # 位置合法且为陆地 - if 0 <= x < m and 0 <= y < n and int(grid[x][y]): - # 更改为水 - grid[x][y] = '0' - # 深度优先搜索,遍历四个方向 - for dx, dy in d: - dfs(x + dx, y + dy) - - count = 0 - for i in range(m): - for j in range(n): - count += int(grid[i][j]) - # 让一个岛屿变成水 - dfs(i, j) - - return count - - -# 深度优先搜索。创建数组记录访问状态 -class Solution2(object): - def numIslands(self, grid): - if not grid: - return 0 - - m, n = len(grid), len(grid[0]) - visited = [[0]*n for _ in range(m)] - d = ((1, 0), (-1, 0), (0, 1), (0, -1)) - - def dfs(x, y): - visited[x][y] = 1 - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == '1' and visited[nx][ny] == 0: - dfs(nx, ny) - - count = 0 - for i in range(m): - for j in range(n): - if grid[i][j] == '1' and visited[i][j] == 0: - count += 1 - dfs(i, j) - - return count - - -# 深度优先搜索。简洁版 -class Solution3(object): - def numIslands(self, grid): - def sink(x, y): - if 0 <= x < len(grid) and 0 <= len(grid[0]) < y and int(grid[x][y]): - grid[x][y] = '0' - for dx, dy in zip((1, -1, 0, 0), (0, 0, 1, -1)): - sink(x + dx, y + dy) - return 1 - return 0 - return sum(sink(i, j) for i in range(len(grid)) for j in range(len(grid[0]))) - - -# 广度优先遍历 -class Solution4(object): - def numIslands(self, grid): - if not grid: - return 0 - - m, n = len(grid), len(grid[0]) - d = ((1, 0), (-1, 0), (0, 1), (0, -1)) - - count = 0 - for i in range(m): - for j in range(n): - if int(grid[i][j]): - count += 1 - q = collections.deque() - q.appendleft((i, j)) - while q: - x, y = q.pop() - if int(grid[x][y]): - grid[x][y] = '0' - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and int(grid[nx][ny]): - q.appendleft((nx, ny)) - - return count - - -# 并查集 -class Solution5(object): - def numIslands(self, grid): - if not grid: - return 0 - - m, n = len(grid), len(grid[0]) - # 记录每个结点的父亲 - d = {} - - # 查找 - def find(x): - # x的父亲不是自己,即不是根结点 - while d[x] != x: - # 逐级往上找x的父亲的父亲 - x = d[d[x]] - # 返回根结点 - return x - - for i in range(m): - for j in range(n): - if grid[i][j] == '1': - # 若字典有键(i, j)(1),则其值为键(i, j)(1)对应的值;否则设置键(i, j)(1)的值为(i, j)(2) - d.setdefault((i, j), (i, j)) - # 上边是陆地 - if i > 0 and grid[i-1][j] == '1': - # 上边结点的根作为当前结点的根的父亲,即合并 - d[find((i, j))] = find((i-1, j)) - # 左边是陆地 - if j > 0 and grid[i][j-1] == '1': - # 左边结点的根作为当前结点的根的父亲 - d[find((i, j))] = find((i, j-1)) - +# 深度优先搜索。原数组修改标志 +class Solution(object): + def numIslands(self, grid): + if not grid: + return 0 + + m, n = len(grid), len(grid[0]) + d = ((1, 0), (-1, 0), (0, 1), (0, -1)) + + def dfs(x, y): + # 位置合法且为陆地 + if 0 <= x < m and 0 <= y < n and int(grid[x][y]): + # 更改为水 + grid[x][y] = '0' + # 深度优先搜索,遍历四个方向 + for dx, dy in d: + dfs(x + dx, y + dy) + + count = 0 + for i in range(m): + for j in range(n): + count += int(grid[i][j]) + # 让一个岛屿变成水 + dfs(i, j) + + return count + + +# 深度优先搜索。创建数组记录访问状态 +class Solution2(object): + def numIslands(self, grid): + if not grid: + return 0 + + m, n = len(grid), len(grid[0]) + visited = [[0]*n for _ in range(m)] + d = ((1, 0), (-1, 0), (0, 1), (0, -1)) + + def dfs(x, y): + visited[x][y] = 1 + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == '1' and visited[nx][ny] == 0: + dfs(nx, ny) + + count = 0 + for i in range(m): + for j in range(n): + if grid[i][j] == '1' and visited[i][j] == 0: + count += 1 + dfs(i, j) + + return count + + +# 深度优先搜索。简洁版 +class Solution3(object): + def numIslands(self, grid): + def sink(x, y): + if 0 <= x < len(grid) and 0 <= len(grid[0]) < y and int(grid[x][y]): + grid[x][y] = '0' + for dx, dy in zip((1, -1, 0, 0), (0, 0, 1, -1)): + sink(x + dx, y + dy) + return 1 + return 0 + return sum(sink(i, j) for i in range(len(grid)) for j in range(len(grid[0]))) + + +# 广度优先遍历 +class Solution4(object): + def numIslands(self, grid): + if not grid: + return 0 + + m, n = len(grid), len(grid[0]) + d = ((1, 0), (-1, 0), (0, 1), (0, -1)) + + count = 0 + for i in range(m): + for j in range(n): + if int(grid[i][j]): + count += 1 + q = collections.deque() + q.appendleft((i, j)) + while q: + x, y = q.pop() + if int(grid[x][y]): + grid[x][y] = '0' + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and int(grid[nx][ny]): + q.appendleft((nx, ny)) + + return count + + +# 并查集 +class Solution5(object): + def numIslands(self, grid): + if not grid: + return 0 + + m, n = len(grid), len(grid[0]) + # 记录每个结点的父亲 + d = {} + + # 查找 + def find(x): + # x的父亲不是自己,即不是根结点 + while d[x] != x: + # 逐级往上找x的父亲的父亲 + x = d[d[x]] + # 返回根结点 + return x + + for i in range(m): + for j in range(n): + if grid[i][j] == '1': + # 若字典有键(i, j)(1),则其值为键(i, j)(1)对应的值;否则设置键(i, j)(1)的值为(i, j)(2) + d.setdefault((i, j), (i, j)) + # 上边是陆地 + if i > 0 and grid[i-1][j] == '1': + # 上边结点的根作为当前结点的根的父亲,即合并 + d[find((i, j))] = find((i-1, j)) + # 左边是陆地 + if j > 0 and grid[i][j-1] == '1': + # 左边结点的根作为当前结点的根的父亲 + d[find((i, j))] = find((i, j-1)) + return len(set([find(x) for x in d.keys()])) \ No newline at end of file diff --git "a/leetcode/202.\345\277\253\344\271\220\346\225\260.py" "b/leetcode_Python/202.\345\277\253\344\271\220\346\225\260.py" similarity index 97% rename from "leetcode/202.\345\277\253\344\271\220\346\225\260.py" rename to "leetcode_Python/202.\345\277\253\344\271\220\346\225\260.py" index b9b0a02..16046c0 100644 --- "a/leetcode/202.\345\277\253\344\271\220\346\225\260.py" +++ "b/leetcode_Python/202.\345\277\253\344\271\220\346\225\260.py" @@ -1,8 +1,8 @@ -# 所有不快乐数的数位平方和计算,最后都会进入 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 的循环中 -class Solution(object): - def isHappy(self, n): - while n != 1: - n = sum(map(lambda x: x**2, map(int, str(n)))) - if n == 4: - return False +# 所有不快乐数的数位平方和计算,最后都会进入 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 的循环中 +class Solution(object): + def isHappy(self, n): + while n != 1: + n = sum(map(lambda x: x**2, map(int, str(n)))) + if n == 4: + return False return True \ No newline at end of file diff --git "a/leetcode/203.\347\247\273\351\231\244\351\223\276\350\241\250\345\205\203\347\264\240.py" "b/leetcode_Python/203.\347\247\273\351\231\244\351\223\276\350\241\250\345\205\203\347\264\240.py" similarity index 96% rename from "leetcode/203.\347\247\273\351\231\244\351\223\276\350\241\250\345\205\203\347\264\240.py" rename to "leetcode_Python/203.\347\247\273\351\231\244\351\223\276\350\241\250\345\205\203\347\264\240.py" index 834ae9a..5d79741 100644 --- "a/leetcode/203.\347\247\273\351\231\244\351\223\276\350\241\250\345\205\203\347\264\240.py" +++ "b/leetcode_Python/203.\347\247\273\351\231\244\351\223\276\350\241\250\345\205\203\347\264\240.py" @@ -1,23 +1,23 @@ -# 若当前结点的下一结点是要删除的元素,则将当前结点的next指针指向下下个结点 -# 写法一 -class Solution(object): - def removeElements(self, head, val): - res = h = ListNode(0) - h.next = head - while h: - while h.next and h.next.val == val: - h.next = h.next.next - h = h.next - return res.next - -# 写法二 -class Solution(object): - def removeElements(self, head, val): - res = h = ListNode(0) - h.next = head - while h.next: - if h.next.val == val: - h.next = h.next.next - else: - h = h.next +# 若当前结点的下一结点是要删除的元素,则将当前结点的next指针指向下下个结点 +# 写法一 +class Solution(object): + def removeElements(self, head, val): + res = h = ListNode(0) + h.next = head + while h: + while h.next and h.next.val == val: + h.next = h.next.next + h = h.next + return res.next + +# 写法二 +class Solution(object): + def removeElements(self, head, val): + res = h = ListNode(0) + h.next = head + while h.next: + if h.next.val == val: + h.next = h.next.next + else: + h = h.next return res.next \ No newline at end of file diff --git "a/leetcode/204.\350\256\241\346\225\260\350\264\250\346\225\260.py" "b/leetcode_Python/204.\350\256\241\346\225\260\350\264\250\346\225\260.py" similarity index 98% rename from "leetcode/204.\350\256\241\346\225\260\350\264\250\346\225\260.py" rename to "leetcode_Python/204.\350\256\241\346\225\260\350\264\250\346\225\260.py" index 3190f1c..945da18 100644 --- "a/leetcode/204.\350\256\241\346\225\260\350\264\250\346\225\260.py" +++ "b/leetcode_Python/204.\350\256\241\346\225\260\350\264\250\346\225\260.py" @@ -1,15 +1,15 @@ -# 厄拉多塞筛法:先将 2~n 的各个数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数; -# 第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数; -# 现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数…… -# 依次类推,一直到所有小于或等于 n 的各数都画了圈或划去为止。 -# 这时,表中画了圈的以及未划去的那些数正好就是小于 n 的素数。 -class Solution(object): - def countPrimes(self, n): - if n < 3: - return 0 - primes = [1]*n - primes[0] = primes[1] = 0 - for i in range(2, int(n**0.5)+1): - if primes[i]: - primes[i*i:n:i] = [0]*(len(primes[i*i:n:i])) +# 厄拉多塞筛法:先将 2~n 的各个数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数; +# 第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数; +# 现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数…… +# 依次类推,一直到所有小于或等于 n 的各数都画了圈或划去为止。 +# 这时,表中画了圈的以及未划去的那些数正好就是小于 n 的素数。 +class Solution(object): + def countPrimes(self, n): + if n < 3: + return 0 + primes = [1]*n + primes[0] = primes[1] = 0 + for i in range(2, int(n**0.5)+1): + if primes[i]: + primes[i*i:n:i] = [0]*(len(primes[i*i:n:i])) return sum(primes) \ No newline at end of file diff --git "a/leetcode/205.\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/205.\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "leetcode/205.\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/205.\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262.py" index 9c2c1a5..ff32915 100644 --- "a/leetcode/205.\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/205.\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262.py" @@ -1,14 +1,14 @@ -# 方法一:若同构则查找字符的索引相同 -class Solution(object): - def isIsomorphic(self, s, t): - for i in range(len(s)): - if s.find(s[i]) != t.find(t[i]): - return False - return True - -# 方法二:判断两字符串去重 与 压缩再去重的长度是否相同 -class Solution(object): - def isIsomorphic(self, s, t): - if len(s) != len(t): - return False +# 方法一:若同构则查找字符的索引相同 +class Solution(object): + def isIsomorphic(self, s, t): + for i in range(len(s)): + if s.find(s[i]) != t.find(t[i]): + return False + return True + +# 方法二:判断两字符串去重 与 压缩再去重的长度是否相同 +class Solution(object): + def isIsomorphic(self, s, t): + if len(s) != len(t): + return False return len(set(zip(s, t))) == len(set(s)) == len(set(t)) \ No newline at end of file diff --git "a/leetcode/206.\345\217\215\350\275\254\351\223\276\350\241\250.py" "b/leetcode_Python/206.\345\217\215\350\275\254\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/206.\345\217\215\350\275\254\351\223\276\350\241\250.py" rename to "leetcode_Python/206.\345\217\215\350\275\254\351\223\276\350\241\250.py" index 877c28c..a5a010e 100644 --- "a/leetcode/206.\345\217\215\350\275\254\351\223\276\350\241\250.py" +++ "b/leetcode_Python/206.\345\217\215\350\275\254\351\223\276\350\241\250.py" @@ -1,23 +1,23 @@ -# 方法一:使用三个指针分别指向前一个、当前、下一个结点 -class Solution(object): - def reverseList(self, head): - before = None - while head: - after = head.next - head.next = before - before = head - head = after - return before - -# 方法二:递归 -class Solution(object): - def reverseList(self, head): - - def reverse(head, before): - if head: - after = head.next - head.next = before - return reverse(after, head) - return before - +# 方法一:使用三个指针分别指向前一个、当前、下一个结点 +class Solution(object): + def reverseList(self, head): + before = None + while head: + after = head.next + head.next = before + before = head + head = after + return before + +# 方法二:递归 +class Solution(object): + def reverseList(self, head): + + def reverse(head, before): + if head: + after = head.next + head.next = before + return reverse(after, head) + return before + return reverse(head, None) \ No newline at end of file diff --git "a/leetcode/207.\350\257\276\347\250\213\350\241\250.py" "b/leetcode_Python/207.\350\257\276\347\250\213\350\241\250.py" similarity index 97% rename from "leetcode/207.\350\257\276\347\250\213\350\241\250.py" rename to "leetcode_Python/207.\350\257\276\347\250\213\350\241\250.py" index f00cbeb..591c360 100644 --- "a/leetcode/207.\350\257\276\347\250\213\350\241\250.py" +++ "b/leetcode_Python/207.\350\257\276\347\250\213\350\241\250.py" @@ -1,68 +1,68 @@ -# 拓扑排序。构建邻接表,每一个结点存放后继结点的集合。若不存在循环,则存在拓扑排序,即最终顶点个数与课程数相同 -class Solution(object): - def canFinish(self, numCourses, prerequisites): - if not numCourses: - return True - # 初始化入度和邻接表 - in_degrees = [0 for _ in range(numCourses)] - adj = [set() for _ in range(numCourses)] - # 更新入度和邻接表 - for second, first in prerequisites: - in_degrees[second] += 1 - adj[first].add(second) - # 将入度为0的结点添加到队列 - queue = [] - for i in range(numCourses): - if in_degrees[i] == 0: - queue.append(i) - - count = 0 - while queue: - # 弹出入度为0的结点并统计个数 - top = queue.pop(0) - count += 1 - # 将该结点的所有邻接点入度减1,若邻接点入度为0则将其添加到队列中 - for successor in adj[top]: - in_degrees[successor] -= 1 - if in_degrees[successor] == 0: - queue.append(successor) - - return count == numCourses - - -# 构建逆邻接表,实现深度优先遍历,当访问一个结点的时,递归访问它的前驱结点,直至前驱结点没有前驱结点为止。 -# 检测这个有向图中有没有环,只要存在环,课程就不能完成。 -class Solution2(object): - def canFinish(self, numCourses, prerequisites): - if not numCourses: - return True - # 初始化已访问表和逆邻接表 - visited = [0 for _ in range(numCourses)] - inverse_adj = [set() for _ in range(numCourses)] - # 更新逆邻接表 - for second, first in prerequisites: - inverse_adj[second].add(first) - # 遍历每个结点作为出发点,递归访问它的前驱结点,若遇到有环则退出 - for i in range(numCourses): - if self.dfs(i, inverse_adj, visited): - return False - return True - - # 方法作用:传入结点,判断、更新结点状态,返回是否有环 - def dfs(self, vertex, inverse_adj, visited): - # 访问新结点时判断该结点当前状态 - # 2表示正在被访问,说明有环 - if visited[vertex] == 2: - return True - # 1表示已访问过,该结点安全 - if visited[vertex] == 1: - return False - # 0表示未访问过,先置为2正在访问 - visited[vertex] = 2 - # 递归访问该结点的前驱结点 - for precursor in inverse_adj[vertex]: - if self.dfs(precursor, inverse_adj, visited): - return True - # 递归完成,无环,回溯,置为1已访问 - visited[vertex] = 1 +# 拓扑排序。构建邻接表,每一个结点存放后继结点的集合。若不存在循环,则存在拓扑排序,即最终顶点个数与课程数相同 +class Solution(object): + def canFinish(self, numCourses, prerequisites): + if not numCourses: + return True + # 初始化入度和邻接表 + in_degrees = [0 for _ in range(numCourses)] + adj = [set() for _ in range(numCourses)] + # 更新入度和邻接表 + for second, first in prerequisites: + in_degrees[second] += 1 + adj[first].add(second) + # 将入度为0的结点添加到队列 + queue = [] + for i in range(numCourses): + if in_degrees[i] == 0: + queue.append(i) + + count = 0 + while queue: + # 弹出入度为0的结点并统计个数 + top = queue.pop(0) + count += 1 + # 将该结点的所有邻接点入度减1,若邻接点入度为0则将其添加到队列中 + for successor in adj[top]: + in_degrees[successor] -= 1 + if in_degrees[successor] == 0: + queue.append(successor) + + return count == numCourses + + +# 构建逆邻接表,实现深度优先遍历,当访问一个结点的时,递归访问它的前驱结点,直至前驱结点没有前驱结点为止。 +# 检测这个有向图中有没有环,只要存在环,课程就不能完成。 +class Solution2(object): + def canFinish(self, numCourses, prerequisites): + if not numCourses: + return True + # 初始化已访问表和逆邻接表 + visited = [0 for _ in range(numCourses)] + inverse_adj = [set() for _ in range(numCourses)] + # 更新逆邻接表 + for second, first in prerequisites: + inverse_adj[second].add(first) + # 遍历每个结点作为出发点,递归访问它的前驱结点,若遇到有环则退出 + for i in range(numCourses): + if self.dfs(i, inverse_adj, visited): + return False + return True + + # 方法作用:传入结点,判断、更新结点状态,返回是否有环 + def dfs(self, vertex, inverse_adj, visited): + # 访问新结点时判断该结点当前状态 + # 2表示正在被访问,说明有环 + if visited[vertex] == 2: + return True + # 1表示已访问过,该结点安全 + if visited[vertex] == 1: + return False + # 0表示未访问过,先置为2正在访问 + visited[vertex] = 2 + # 递归访问该结点的前驱结点 + for precursor in inverse_adj[vertex]: + if self.dfs(precursor, inverse_adj, visited): + return True + # 递归完成,无环,回溯,置为1已访问 + visited[vertex] = 1 return False \ No newline at end of file diff --git "a/leetcode/208.\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" "b/leetcode_Python/208.\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" similarity index 97% rename from "leetcode/208.\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" rename to "leetcode_Python/208.\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" index 3528da9..cd00326 100644 --- "a/leetcode/208.\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" +++ "b/leetcode_Python/208.\345\256\236\347\216\260 Trie (\345\211\215\347\274\200\346\240\221).py" @@ -1,34 +1,34 @@ -class Trie(object): - - def __init__(self): - self.root = {} - - def insert(self, word): - # 直接赋值引用,同步更新 - node = self.root - # 遍历单词每个字符,逐层向内扩展当前字典树 - for char in word: - node = node.setdefault(char, {}) - # 结尾添加结束标志 - node['end'] = '' - - def search(self, word): - node = self.root - # 遍历单词每个字符,逐层向内更新当前字典树 - for char in word: - if char not in node: - return False - node = node[char] - # 遍历完成,判断最后一个键是否为结束标志 - return 'end' in node - - def startsWith(self, prefix): - node = self.root - # 遍历前缀每个字符,逐层向内更新当前字典树 - for char in prefix: - # 字符不在字典树中,表示前缀不存在 - if char not in node: - return False - node = node[char] - # 前缀遍历完成,表示存在该前缀 +class Trie(object): + + def __init__(self): + self.root = {} + + def insert(self, word): + # 直接赋值引用,同步更新 + node = self.root + # 遍历单词每个字符,逐层向内扩展当前字典树 + for char in word: + node = node.setdefault(char, {}) + # 结尾添加结束标志 + node['end'] = '' + + def search(self, word): + node = self.root + # 遍历单词每个字符,逐层向内更新当前字典树 + for char in word: + if char not in node: + return False + node = node[char] + # 遍历完成,判断最后一个键是否为结束标志 + return 'end' in node + + def startsWith(self, prefix): + node = self.root + # 遍历前缀每个字符,逐层向内更新当前字典树 + for char in prefix: + # 字符不在字典树中,表示前缀不存在 + if char not in node: + return False + node = node[char] + # 前缀遍历完成,表示存在该前缀 return True \ No newline at end of file diff --git "a/leetcode/210.\350\257\276\347\250\213\350\241\250 II.py" "b/leetcode_Python/210.\350\257\276\347\250\213\350\241\250 II.py" similarity index 97% rename from "leetcode/210.\350\257\276\347\250\213\350\241\250 II.py" rename to "leetcode_Python/210.\350\257\276\347\250\213\350\241\250 II.py" index 349e5df..46b2045 100644 --- "a/leetcode/210.\350\257\276\347\250\213\350\241\250 II.py" +++ "b/leetcode_Python/210.\350\257\276\347\250\213\350\241\250 II.py" @@ -1,66 +1,66 @@ -# 拓扑排序。构建邻接表,每一个结点存放后继结点的集合。若不存在循环,则存在拓扑排序,即最终顶点个数与课程数相同 -class Solution(object): - def canFinish(self, numCourses, prerequisites): - # 初始化入度和邻接表 - in_degrees = [0 for _ in range(numCourses)] - adj = [set() for _ in range(numCourses)] - # 更新入度和邻接表 - for second, first in prerequisites: - in_degrees[second] += 1 - adj[first].add(second) - # 将入度为0的结点添加到队列 - queue, res = [], [] - for i in range(numCourses): - if in_degrees[i] == 0: - queue.append(i) - - while queue: - # 弹出入度为0的结点并添加到数组 - top = queue.pop(0) - res.append(top) - # 将该结点的所有邻接点入度减1,若邻接点入度为0则将其添加到队列中 - for successor in adj[top]: - in_degrees[successor] -= 1 - if in_degrees[successor] == 0: - queue.append(successor) - - if len(res) != numCourses: - return [] - return res - - -# 构建逆邻接表,实现深度优先遍历,当访问一个结点的时,递归访问它的前驱结点,直至前驱结点没有前驱结点为止。 -# 检测这个有向图中有没有环,只要存在环,课程就不能完成。 -class Solution2(object): - def canFinish(self, numCourses, prerequisites): - # 初始化已访问表和逆邻接表 - visited = [0 for _ in range(numCourses)] - inverse_adj = [set() for _ in range(numCourses)] - # 更新逆邻接表 - for second, first in prerequisites: - inverse_adj[second].add(first) - # 遍历每个结点作为出发点,递归访问它的前驱结点,若遇到有环则退出 - res = [] - for i in range(numCourses): - if self.dfs(i, inverse_adj, visited, res): - return [] - return res - - def dfs(self, vertex, inverse_adj, visited, res): - # 访问新结点时判断该结点当前状态 - # 2表示正在被访问,说明有环 - if visited[vertex] == 2: - return True - # 1表示已访问过,该结点安全 - if visited[vertex] == 1: - return False - # 0表示未访问过,先置为2正在访问 - visited[vertex] = 2 - # 递归访问该结点的前驱结点 - for precursor in inverse_adj[vertex]: - if self.dfs(precursor, inverse_adj, visited, res): - return True - # 递归完成,没有前驱结点了,回溯,置为1已访问 - visited[vertex] = 1 - res.append(vertex) +# 拓扑排序。构建邻接表,每一个结点存放后继结点的集合。若不存在循环,则存在拓扑排序,即最终顶点个数与课程数相同 +class Solution(object): + def canFinish(self, numCourses, prerequisites): + # 初始化入度和邻接表 + in_degrees = [0 for _ in range(numCourses)] + adj = [set() for _ in range(numCourses)] + # 更新入度和邻接表 + for second, first in prerequisites: + in_degrees[second] += 1 + adj[first].add(second) + # 将入度为0的结点添加到队列 + queue, res = [], [] + for i in range(numCourses): + if in_degrees[i] == 0: + queue.append(i) + + while queue: + # 弹出入度为0的结点并添加到数组 + top = queue.pop(0) + res.append(top) + # 将该结点的所有邻接点入度减1,若邻接点入度为0则将其添加到队列中 + for successor in adj[top]: + in_degrees[successor] -= 1 + if in_degrees[successor] == 0: + queue.append(successor) + + if len(res) != numCourses: + return [] + return res + + +# 构建逆邻接表,实现深度优先遍历,当访问一个结点的时,递归访问它的前驱结点,直至前驱结点没有前驱结点为止。 +# 检测这个有向图中有没有环,只要存在环,课程就不能完成。 +class Solution2(object): + def canFinish(self, numCourses, prerequisites): + # 初始化已访问表和逆邻接表 + visited = [0 for _ in range(numCourses)] + inverse_adj = [set() for _ in range(numCourses)] + # 更新逆邻接表 + for second, first in prerequisites: + inverse_adj[second].add(first) + # 遍历每个结点作为出发点,递归访问它的前驱结点,若遇到有环则退出 + res = [] + for i in range(numCourses): + if self.dfs(i, inverse_adj, visited, res): + return [] + return res + + def dfs(self, vertex, inverse_adj, visited, res): + # 访问新结点时判断该结点当前状态 + # 2表示正在被访问,说明有环 + if visited[vertex] == 2: + return True + # 1表示已访问过,该结点安全 + if visited[vertex] == 1: + return False + # 0表示未访问过,先置为2正在访问 + visited[vertex] = 2 + # 递归访问该结点的前驱结点 + for precursor in inverse_adj[vertex]: + if self.dfs(precursor, inverse_adj, visited, res): + return True + # 递归完成,没有前驱结点了,回溯,置为1已访问 + visited[vertex] = 1 + res.append(vertex) return False \ No newline at end of file diff --git "a/leetcode/211.\346\267\273\345\212\240\344\270\216\346\220\234\347\264\242\345\215\225\350\257\215 - \346\225\260\346\215\256\347\273\223\346\236\204\350\256\276\350\256\241.py" "b/leetcode_Python/211.\346\267\273\345\212\240\344\270\216\346\220\234\347\264\242\345\215\225\350\257\215 - \346\225\260\346\215\256\347\273\223\346\236\204\350\256\276\350\256\241.py" similarity index 96% rename from "leetcode/211.\346\267\273\345\212\240\344\270\216\346\220\234\347\264\242\345\215\225\350\257\215 - \346\225\260\346\215\256\347\273\223\346\236\204\350\256\276\350\256\241.py" rename to "leetcode_Python/211.\346\267\273\345\212\240\344\270\216\346\220\234\347\264\242\345\215\225\350\257\215 - \346\225\260\346\215\256\347\273\223\346\236\204\350\256\276\350\256\241.py" index e594449..8cec784 100644 --- "a/leetcode/211.\346\267\273\345\212\240\344\270\216\346\220\234\347\264\242\345\215\225\350\257\215 - \346\225\260\346\215\256\347\273\223\346\236\204\350\256\276\350\256\241.py" +++ "b/leetcode_Python/211.\346\267\273\345\212\240\344\270\216\346\220\234\347\264\242\345\215\225\350\257\215 - \346\225\260\346\215\256\347\273\223\346\236\204\350\256\276\350\256\241.py" @@ -1,57 +1,57 @@ -# 将单词按照长度归类存到字典中,匹配时逐个遍历比较相同长度的单词 -class WordDictionary(object): - - def __init__(self): - from collections import defaultdict - self.d = defaultdict(list) - - def addWord(self, word): - self.d[len(word)] += [word] - - def search(self, word): - n = len(word) - for w in self.d[n]: - for i in range(n): - if word[i] == '.': - continue - if word[i] != w[i]: - break - else: - return True - return False - - -# 字典树,回溯法 -class WordDictionary(object): - - def __init__(self): - # {'b': {'a': {'d': {'#': {}}}}, 'd': {'a': {'d': {'#': {}}}}, 'm': {'a': {'d': {'#': {}}}}} - self.lookup = {} - - def addWord(self, word): - tree = self.lookup - for a in word: - tree = tree.setdefault(a, {}) - tree["#"] = {} - - def search(self, word): - def helper(word, tree): - # 递归终止条件 - if not word: - # 搜索完最后一个字符 - if "#" in tree: - return True - # 未搜索完 - return False - # 如果字符是'.',需要遍历判断每个字典树 - if word[0] == ".": - for t in tree: - if helper(word[1:], tree[t]): - return True - # 如果字符在字典中,只需要判断该字符的字典树 - elif word[0] in tree: - if helper(word[1:], tree[word[0]]): - return True - # 字符不在字典中 - return False +# 将单词按照长度归类存到字典中,匹配时逐个遍历比较相同长度的单词 +class WordDictionary(object): + + def __init__(self): + from collections import defaultdict + self.d = defaultdict(list) + + def addWord(self, word): + self.d[len(word)] += [word] + + def search(self, word): + n = len(word) + for w in self.d[n]: + for i in range(n): + if word[i] == '.': + continue + if word[i] != w[i]: + break + else: + return True + return False + + +# 字典树,回溯法 +class WordDictionary(object): + + def __init__(self): + # {'b': {'a': {'d': {'#': {}}}}, 'd': {'a': {'d': {'#': {}}}}, 'm': {'a': {'d': {'#': {}}}}} + self.lookup = {} + + def addWord(self, word): + tree = self.lookup + for a in word: + tree = tree.setdefault(a, {}) + tree["#"] = {} + + def search(self, word): + def helper(word, tree): + # 递归终止条件 + if not word: + # 搜索完最后一个字符 + if "#" in tree: + return True + # 未搜索完 + return False + # 如果字符是'.',需要遍历判断每个字典树 + if word[0] == ".": + for t in tree: + if helper(word[1:], tree[t]): + return True + # 如果字符在字典中,只需要判断该字符的字典树 + elif word[0] in tree: + if helper(word[1:], tree[word[0]]): + return True + # 字符不在字典中 + return False return helper(word, self.lookup) \ No newline at end of file diff --git "a/leetcode/215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" "b/leetcode_Python/215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" similarity index 97% rename from "leetcode/215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" rename to "leetcode_Python/215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" index 916b22d..ba14899 100644 --- "a/leetcode/215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" +++ "b/leetcode_Python/215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" @@ -1,10 +1,10 @@ -# 遍历数组,用一个长度为k的列表存放最大的k个数,返回列表中的最小值即为第k大的数 -class Solution(object): - def findKthLargest(self, nums, k): - res = [] - for num in nums: - if len(res) < k: - res.append(num) - elif num > min(res): - res[res.index(min(res))] = num +# 遍历数组,用一个长度为k的列表存放最大的k个数,返回列表中的最小值即为第k大的数 +class Solution(object): + def findKthLargest(self, nums, k): + res = [] + for num in nums: + if len(res) < k: + res.append(num) + elif num > min(res): + res[res.index(min(res))] = num return min(res) \ No newline at end of file diff --git "a/leetcode/216.\347\273\204\345\220\210\346\200\273\345\222\214 III.py" "b/leetcode_Python/216.\347\273\204\345\220\210\346\200\273\345\222\214 III.py" similarity index 97% rename from "leetcode/216.\347\273\204\345\220\210\346\200\273\345\222\214 III.py" rename to "leetcode_Python/216.\347\273\204\345\220\210\346\200\273\345\222\214 III.py" index 78fd7be..001df1e 100644 --- "a/leetcode/216.\347\273\204\345\220\210\346\200\273\345\222\214 III.py" +++ "b/leetcode_Python/216.\347\273\204\345\220\210\346\200\273\345\222\214 III.py" @@ -1,41 +1,41 @@ -class Solution(object): - def combinationSum3(self, k, n): - # 参数:数值数组,输出数组 - def find(nums, output): - # 终止条件 - if len(output) == k and sum(output) == n: - res.append(output) - # 剪枝条件,已有数和剩余数个数之和小于k - elif len(nums) + len(output) < k: - return - else: - # 遍历数值数组,使得每个元素都有机会成为输出数组的下一个元素 - for i in range(len(nums)): - # 数值数组和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - find(nums[i+1:], output + [nums[i]]) - - res = [] - nums = list(range(1, 10)) - find(nums, []) - return res - - -class Solution2(object): - def combinationSum3(self, k, n): - # 参数:数值,输出数组 - def find(num, output): - # 终止条件,将满足条件的结果添加到全局数组,返回空结束当前递归 - if len(output) == k and sum(output) == n: - res.append(output) - return - # 剪枝条件,数值在1-9,返回空结束当前递归 - if num > 9: - return - # 数值和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - find(num + 1, output + [num]) - find(num + 1, output) - - res = [] - # 调用递归,设置初值 - find(1, []) +class Solution(object): + def combinationSum3(self, k, n): + # 参数:数值数组,输出数组 + def find(nums, output): + # 终止条件 + if len(output) == k and sum(output) == n: + res.append(output) + # 剪枝条件,已有数和剩余数个数之和小于k + elif len(nums) + len(output) < k: + return + else: + # 遍历数值数组,使得每个元素都有机会成为输出数组的下一个元素 + for i in range(len(nums)): + # 数值数组和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + find(nums[i+1:], output + [nums[i]]) + + res = [] + nums = list(range(1, 10)) + find(nums, []) + return res + + +class Solution2(object): + def combinationSum3(self, k, n): + # 参数:数值,输出数组 + def find(num, output): + # 终止条件,将满足条件的结果添加到全局数组,返回空结束当前递归 + if len(output) == k and sum(output) == n: + res.append(output) + return + # 剪枝条件,数值在1-9,返回空结束当前递归 + if num > 9: + return + # 数值和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + find(num + 1, output + [num]) + find(num + 1, output) + + res = [] + # 调用递归,设置初值 + find(1, []) return res \ No newline at end of file diff --git "a/leetcode/217.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240.py" "b/leetcode_Python/217.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240.py" similarity index 96% rename from "leetcode/217.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240.py" rename to "leetcode_Python/217.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240.py" index 612b67b..75d79b2 100644 --- "a/leetcode/217.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240.py" +++ "b/leetcode_Python/217.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240.py" @@ -1,8 +1,8 @@ -# 使用集合去重,若长度与原数组相同,则无重复元素,否则有重复 -class Solution(object): - def containsDuplicate(self, nums): - s = set(nums) - if len(s) == len(nums): - return False - return True - +# 使用集合去重,若长度与原数组相同,则无重复元素,否则有重复 +class Solution(object): + def containsDuplicate(self, nums): + s = set(nums) + if len(s) == len(nums): + return False + return True + diff --git "a/leetcode/219.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240II.py" "b/leetcode_Python/219.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240II.py" similarity index 97% rename from "leetcode/219.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240II.py" rename to "leetcode_Python/219.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240II.py" index fac01d4..a32caef 100644 --- "a/leetcode/219.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240II.py" +++ "b/leetcode_Python/219.\345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240II.py" @@ -1,12 +1,12 @@ -# 使用字典,如果元素不在字典中,则更新字典。若在字典中,则计算索引距离,若距离≤k则为True,否则更新字典 -class Solution(object): - def containsNearbyDuplicate(self, nums, k): - d = {} - for i, num in enumerate(nums): - if num not in d: - d[num] = i - else: - if i-d[num] <= k: - return True - d[num] = i +# 使用字典,如果元素不在字典中,则更新字典。若在字典中,则计算索引距离,若距离≤k则为True,否则更新字典 +class Solution(object): + def containsNearbyDuplicate(self, nums, k): + d = {} + for i, num in enumerate(nums): + if num not in d: + d[num] = i + else: + if i-d[num] <= k: + return True + d[num] = i return False \ No newline at end of file diff --git "a/leetcode/221.\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.py" "b/leetcode_Python/221.\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.py" similarity index 97% rename from "leetcode/221.\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.py" rename to "leetcode_Python/221.\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.py" index 9fb31df..4663374 100644 --- "a/leetcode/221.\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.py" +++ "b/leetcode_Python/221.\346\234\200\345\244\247\346\255\243\346\226\271\345\275\242.py" @@ -1,22 +1,22 @@ -# dp[i][j]表示以i, j位置为右下角顶点能组成的最大正方形的边长 -# 当matrix[i][j]=1时,能组成的正方形为左边、上边、左上能组成的正方形边长的最小值加1 -# 最小值是因为只要存在一个0,就没法组成更大的正方形 -class Solution(object): - def maximalSquare(self, matrix): - m = len(matrix) - if m == 0: - return 0 - n = len(matrix[0]) - dp = [[0]*n for _ in range(m)] - # 初始化数组 - for i in range(n): - dp[0][i] = int(matrix[0][i]) - for j in range(m): - dp[j][0] = int(matrix[j][0]) - # 遍历每个位置,记录状态值 - for i in range(1, m): - for j in range(1, n): - if matrix[i][j] == '1': - dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) - +# dp[i][j]表示以i, j位置为右下角顶点能组成的最大正方形的边长 +# 当matrix[i][j]=1时,能组成的正方形为左边、上边、左上能组成的正方形边长的最小值加1 +# 最小值是因为只要存在一个0,就没法组成更大的正方形 +class Solution(object): + def maximalSquare(self, matrix): + m = len(matrix) + if m == 0: + return 0 + n = len(matrix[0]) + dp = [[0]*n for _ in range(m)] + # 初始化数组 + for i in range(n): + dp[0][i] = int(matrix[0][i]) + for j in range(m): + dp[j][0] = int(matrix[j][0]) + # 遍历每个位置,记录状态值 + for i in range(1, m): + for j in range(1, n): + if matrix[i][j] == '1': + dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + return max(map(max, dp)) ** 2 \ No newline at end of file diff --git "a/leetcode/222.\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221\347\232\204\350\212\202\347\202\271\344\270\252\346\225\260.py" "b/leetcode_Python/222.\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221\347\232\204\350\212\202\347\202\271\344\270\252\346\225\260.py" similarity index 97% rename from "leetcode/222.\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221\347\232\204\350\212\202\347\202\271\344\270\252\346\225\260.py" rename to "leetcode_Python/222.\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221\347\232\204\350\212\202\347\202\271\344\270\252\346\225\260.py" index 1bfb7db..daf1009 100644 --- "a/leetcode/222.\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221\347\232\204\350\212\202\347\202\271\344\270\252\346\225\260.py" +++ "b/leetcode_Python/222.\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221\347\232\204\350\212\202\347\202\271\344\270\252\346\225\260.py" @@ -1,17 +1,17 @@ -# 寻找左子树的最左边的高度和右子树的最右边的高度,如果相同则为满二叉树,高度为2^h-1, 否则递归左子树和右子树 -# 方法作用极简化:求满二叉树的结点个数。若树不是满二叉树,则递归判断左右子树是否为满二叉树并求结点个数 -class Solution(object): - def countNodes(self, root): - if not root: - return 0 - p, q = root, root - lhigh = rhigh = 0 - while p: - p = p.left - lhigh += 1 - while q: - q = q.right - rhigh += 1 - if lhigh == rhigh: - return int(math.pow(2, lhigh)-1) +# 寻找左子树的最左边的高度和右子树的最右边的高度,如果相同则为满二叉树,高度为2^h-1, 否则递归左子树和右子树 +# 方法作用极简化:求满二叉树的结点个数。若树不是满二叉树,则递归判断左右子树是否为满二叉树并求结点个数 +class Solution(object): + def countNodes(self, root): + if not root: + return 0 + p, q = root, root + lhigh = rhigh = 0 + while p: + p = p.left + lhigh += 1 + while q: + q = q.right + rhigh += 1 + if lhigh == rhigh: + return int(math.pow(2, lhigh)-1) return 1 + self.countNodes(root.left) + self.countNodes(root.right) \ No newline at end of file diff --git "a/leetcode/223.\347\237\251\345\275\242\351\235\242\347\247\257.py" "b/leetcode_Python/223.\347\237\251\345\275\242\351\235\242\347\247\257.py" similarity index 97% rename from "leetcode/223.\347\237\251\345\275\242\351\235\242\347\247\257.py" rename to "leetcode_Python/223.\347\237\251\345\275\242\351\235\242\347\247\257.py" index 7cee4e6..d475d6f 100644 --- "a/leetcode/223.\347\237\251\345\275\242\351\235\242\347\247\257.py" +++ "b/leetcode_Python/223.\347\237\251\345\275\242\351\235\242\347\247\257.py" @@ -1,10 +1,10 @@ -class Solution(object): - def computeArea(self, A, B, C, D, E, F, G, H): - # 两个矩形的面积 - a = (C-A) * (D-B) - b = (G-E) * (H-F) - # 重叠部分的面积 - x = max(0, min(C, G) - max(A, E)) - y = max(0, min(D, H) - max(B, F)) - area = a+b-x*y +class Solution(object): + def computeArea(self, A, B, C, D, E, F, G, H): + # 两个矩形的面积 + a = (C-A) * (D-B) + b = (G-E) * (H-F) + # 重叠部分的面积 + x = max(0, min(C, G) - max(A, E)) + y = max(0, min(D, H) - max(B, F)) + area = a+b-x*y return area \ No newline at end of file diff --git "a/leetcode/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" "b/leetcode_Python/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" similarity index 94% rename from "leetcode/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" rename to "leetcode_Python/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" index 689a6de..aff660c 100644 --- "a/leetcode/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" +++ "b/leetcode_Python/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" @@ -1,16 +1,16 @@ -class MyStack(object): - - def __init__(self): - self.stack = [] - - def push(self, x): - self.stack.append(x) - - def pop(self): - return self.stack.pop() - - def top(self): - return self.stack[-1] - - def empty(self): +class MyStack(object): + + def __init__(self): + self.stack = [] + + def push(self, x): + self.stack.append(x) + + def pop(self): + return self.stack.pop() + + def top(self): + return self.stack[-1] + + def empty(self): return self.stack == [] \ No newline at end of file diff --git "a/leetcode/226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.py" index 9734952..1a20c07 100644 --- "a/leetcode/226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.py" @@ -1,9 +1,9 @@ -# 递归,左右结点交换 -class Solution(object): - def invertTree(self, root): - if not root: - return None - root.left, root.right = root.right, root.left - self.invertTree(root.left) - self.invertTree(root.right) +# 递归,左右结点交换 +class Solution(object): + def invertTree(self, root): + if not root: + return None + root.left, root.right = root.right, root.left + self.invertTree(root.left) + self.invertTree(root.right) return root \ No newline at end of file diff --git "a/leetcode/230.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\254\254K\345\260\217\347\232\204\345\205\203\347\264\240.py" "b/leetcode_Python/230.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\254\254K\345\260\217\347\232\204\345\205\203\347\264\240.py" similarity index 96% rename from "leetcode/230.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\254\254K\345\260\217\347\232\204\345\205\203\347\264\240.py" rename to "leetcode_Python/230.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\254\254K\345\260\217\347\232\204\345\205\203\347\264\240.py" index b75ecd6..165171c 100644 --- "a/leetcode/230.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\254\254K\345\260\217\347\232\204\345\205\203\347\264\240.py" +++ "b/leetcode_Python/230.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\254\254K\345\260\217\347\232\204\345\205\203\347\264\240.py" @@ -1,36 +1,36 @@ -# 方法一:用数组存放中序遍历结果 -class Solution(object): - def __init__(self): - self.res = [] - - def kthSmallest(self, root, k): - self.inorder(root) - return self.res[k-1] - - def inorder(self, root): - if not root: - return - self.inorder(root.left) - self.res.append(root.val) - self.inorder(root.right) - -# 方法二: -# 如果root的左子树结点数量是k-1,那么root就刚好是第k个 -# 如果k小于左子树结点数量,则递归判断root.left -# 如果k大于左子树结点数量,则递归判断root.right,k减去左子树和根的结点个数 -class Solution(object): - def kthSmallest(self, root, k): - def count(root): - if not root: - return 0 - return count(root.left) + count(root.right) + 1 - - if not root: - return - left = count(root.left) - if left == k-1: - return root.val - elif left > k-1: - return self.kthSmallest(root.left, k) - else: +# 方法一:用数组存放中序遍历结果 +class Solution(object): + def __init__(self): + self.res = [] + + def kthSmallest(self, root, k): + self.inorder(root) + return self.res[k-1] + + def inorder(self, root): + if not root: + return + self.inorder(root.left) + self.res.append(root.val) + self.inorder(root.right) + +# 方法二: +# 如果root的左子树结点数量是k-1,那么root就刚好是第k个 +# 如果k小于左子树结点数量,则递归判断root.left +# 如果k大于左子树结点数量,则递归判断root.right,k减去左子树和根的结点个数 +class Solution(object): + def kthSmallest(self, root, k): + def count(root): + if not root: + return 0 + return count(root.left) + count(root.right) + 1 + + if not root: + return + left = count(root.left) + if left == k-1: + return root.val + elif left > k-1: + return self.kthSmallest(root.left, k) + else: return self.kthSmallest(root.right, k-left-1) \ No newline at end of file diff --git "a/leetcode/231.2\347\232\204\345\271\202.py" "b/leetcode_Python/231.2\347\232\204\345\271\202.py" similarity index 97% rename from "leetcode/231.2\347\232\204\345\271\202.py" rename to "leetcode_Python/231.2\347\232\204\345\271\202.py" index bb649fa..fffb8eb 100644 --- "a/leetcode/231.2\347\232\204\345\271\202.py" +++ "b/leetcode_Python/231.2\347\232\204\345\271\202.py" @@ -1,8 +1,8 @@ -# 因子可全由2组成,除尽2判断最终结果是否等于1 -class Solution(object): - def isPowerOfTwo(self, n): - if n==0: - return False - while n%2 == 0: - n /= 2 +# 因子可全由2组成,除尽2判断最终结果是否等于1 +class Solution(object): + def isPowerOfTwo(self, n): + if n==0: + return False + while n%2 == 0: + n /= 2 return n == 1 \ No newline at end of file diff --git "a/leetcode/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" "b/leetcode_Python/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" similarity index 94% rename from "leetcode/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" rename to "leetcode_Python/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" index 00c2d3f..69746aa 100644 --- "a/leetcode/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" +++ "b/leetcode_Python/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.py" @@ -1,16 +1,16 @@ -class MyQueue(object): - - def __init__(self): - self.queue = [] - - def push(self, x): - self.queue.append(x) - - def pop(self): - return self.queue.pop(0) - - def peek(self): - return self.queue[0] - - def empty(self): +class MyQueue(object): + + def __init__(self): + self.queue = [] + + def push(self, x): + self.queue.append(x) + + def pop(self): + return self.queue.pop(0) + + def peek(self): + return self.queue[0] + + def empty(self): return self.queue == [] \ No newline at end of file diff --git "a/leetcode/234.\345\233\236\346\226\207\351\223\276\350\241\250.py" "b/leetcode_Python/234.\345\233\236\346\226\207\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/234.\345\233\236\346\226\207\351\223\276\350\241\250.py" rename to "leetcode_Python/234.\345\233\236\346\226\207\351\223\276\350\241\250.py" index 2df3894..925a159 100644 --- "a/leetcode/234.\345\233\236\346\226\207\351\223\276\350\241\250.py" +++ "b/leetcode_Python/234.\345\233\236\346\226\207\351\223\276\350\241\250.py" @@ -1,31 +1,31 @@ -# 方法一:将结点值添加到数组,反转数组看是否相同 -class Solution(object): - def isPalindrome(self, head): - res = [] - while head: - res.append(head.val) - head = head.next - return res[:] == res[::-1] - -# 方法二:将链表分为两半,反转后半部分链表,与前半部分链表比较是否相同 -class Solution(object): - def isPalindrome(self, head): - fast = slow = head - # 找到中间节点 - while fast and fast.next: - fast = fast.next.next - slow = slow.next - # 翻转后半部分 - before = None - while slow: - after = slow.next - slow.next = before - before = slow - slow = after - # 比较前后两部分 - while before: - if before.val != head.val: - return False - before = before.next - head = head.next +# 方法一:将结点值添加到数组,反转数组看是否相同 +class Solution(object): + def isPalindrome(self, head): + res = [] + while head: + res.append(head.val) + head = head.next + return res[:] == res[::-1] + +# 方法二:将链表分为两半,反转后半部分链表,与前半部分链表比较是否相同 +class Solution(object): + def isPalindrome(self, head): + fast = slow = head + # 找到中间节点 + while fast and fast.next: + fast = fast.next.next + slow = slow.next + # 翻转后半部分 + before = None + while slow: + after = slow.next + slow.next = before + before = slow + slow = after + # 比较前后两部分 + while before: + if before.val != head.val: + return False + before = before.next + head = head.next return True \ No newline at end of file diff --git "a/leetcode/235.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" "b/leetcode_Python/235.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" similarity index 98% rename from "leetcode/235.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" rename to "leetcode_Python/235.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" index 47c4d38..6336fff 100644 --- "a/leetcode/235.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" +++ "b/leetcode_Python/235.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" @@ -1,10 +1,10 @@ -# 两个结点在根结点两边则共同祖先是root,在同一边则递归判断 -class Solution(object): - def lowestCommonAncestor(self, root, p, q): - if not root: - return - if root.val > p.val and root.val > q.val: - return self.lowestCommonAncestor(root.left, p, q) - if root.val < p.val and root.val < q.val: - return self.lowestCommonAncestor(root.right, p, q) +# 两个结点在根结点两边则共同祖先是root,在同一边则递归判断 +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + if not root: + return + if root.val > p.val and root.val > q.val: + return self.lowestCommonAncestor(root.left, p, q) + if root.val < p.val and root.val < q.val: + return self.lowestCommonAncestor(root.right, p, q) return root \ No newline at end of file diff --git "a/leetcode/236.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" "b/leetcode_Python/236.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" similarity index 97% rename from "leetcode/236.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" rename to "leetcode_Python/236.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" index 4ffbaa1..64cb2ae 100644 --- "a/leetcode/236.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" +++ "b/leetcode_Python/236.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.py" @@ -1,14 +1,14 @@ -class Solution(object): - def lowestCommonAncestor(self, root, p, q): - # 找p、q结点,找到则返回该结点 - if not root or root==p or root==q: - return root - # 在左子树找p、q结点 - left = self.lowestCommonAncestor(root.left, p, q) - # 在右子树找p、q结点 - right = self.lowestCommonAncestor(root.right, p, q) - # p、q结点分别在左子树和右子树,最近公共祖先就是根 - if left and right: - return root - # p、q结点同时在左子树或右子树 +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + # 找p、q结点,找到则返回该结点 + if not root or root==p or root==q: + return root + # 在左子树找p、q结点 + left = self.lowestCommonAncestor(root.left, p, q) + # 在右子树找p、q结点 + right = self.lowestCommonAncestor(root.right, p, q) + # p、q结点分别在左子树和右子树,最近公共祖先就是根 + if left and right: + return root + # p、q结点同时在左子树或右子树 return left or right \ No newline at end of file diff --git "a/leetcode/237.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" "b/leetcode_Python/237.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" similarity index 97% rename from "leetcode/237.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" rename to "leetcode_Python/237.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" index 5dae9fb..cc86408 100644 --- "a/leetcode/237.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" +++ "b/leetcode_Python/237.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\347\232\204\347\273\223\347\202\271.py" @@ -1,15 +1,15 @@ -# 方法一 -class Solution(object): - def deleteNode(self, node): - # 把下一位的值赋给待删值 - node.val = node.next.val - # 结点得到新值,next指针指向下下位,即删除了一个同值结点 - node.next = node.next.next - -# 方法二:依次往前赋值,将倒数第二个结点的next指向空,即删除了最后一个同值结点 -class Solution(object): - def deleteNode(self, node): - while node.next: - node.val = node.next.val - pre, node = node, node.next +# 方法一 +class Solution(object): + def deleteNode(self, node): + # 把下一位的值赋给待删值 + node.val = node.next.val + # 结点得到新值,next指针指向下下位,即删除了一个同值结点 + node.next = node.next.next + +# 方法二:依次往前赋值,将倒数第二个结点的next指向空,即删除了最后一个同值结点 +class Solution(object): + def deleteNode(self, node): + while node.next: + node.val = node.next.val + pre, node = node, node.next pre.next = None \ No newline at end of file diff --git "a/leetcode/238.\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" "b/leetcode_Python/238.\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" similarity index 96% rename from "leetcode/238.\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" rename to "leetcode_Python/238.\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" index 81b4e0f..dba513a 100644 --- "a/leetcode/238.\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" +++ "b/leetcode_Python/238.\351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.py" @@ -1,35 +1,35 @@ -# 方法一:分类讨论 -class Solution(object): - def productExceptSelf(self, nums): - z = nums.count(0) - # 大于1个0的情况,累积结果全部为0 - if z > 1: - return [0]*len(nums) - # 1个0的情况,除了0位置,其他都为0 - if z == 1: - res = [0]*len(nums) - index = nums.index(0) - nums.pop(index) - r = 1 - for num in nums: - r *= num - res[index] = r - return res - # 没有0的情况,先算累积,再用总积去除逐个位置的数 - res = 1 - for num in nums: - res *= num - return [res/i for i in nums] - - -# 方法二:当前数 = 左边的乘积 x 右边的乘积 -class Solution(object): - def productExceptSelf(self, nums): - n = len(nums) - l, r, res = 1, 1, [1]*n - for i in range(n): - res[i] *= l - l *= nums[i] - res[n-1-i] *= r - r *= nums[n-1-i] +# 方法一:分类讨论 +class Solution(object): + def productExceptSelf(self, nums): + z = nums.count(0) + # 大于1个0的情况,累积结果全部为0 + if z > 1: + return [0]*len(nums) + # 1个0的情况,除了0位置,其他都为0 + if z == 1: + res = [0]*len(nums) + index = nums.index(0) + nums.pop(index) + r = 1 + for num in nums: + r *= num + res[index] = r + return res + # 没有0的情况,先算累积,再用总积去除逐个位置的数 + res = 1 + for num in nums: + res *= num + return [res/i for i in nums] + + +# 方法二:当前数 = 左边的乘积 x 右边的乘积 +class Solution(object): + def productExceptSelf(self, nums): + n = len(nums) + l, r, res = 1, 1, [1]*n + for i in range(n): + res[i] *= l + l *= nums[i] + res[n-1-i] *= r + r *= nums[n-1-i] return res \ No newline at end of file diff --git "a/leetcode/242.\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.py" "b/leetcode_Python/242.\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.py" similarity index 96% rename from "leetcode/242.\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.py" rename to "leetcode_Python/242.\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.py" index 9ac7d0f..c56353b 100644 --- "a/leetcode/242.\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.py" +++ "b/leetcode_Python/242.\346\234\211\346\225\210\347\232\204\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.py" @@ -1,11 +1,11 @@ -# 使用字典,判断两个字符串中字符的个数是否相同 -class Solution(object): - def isAnagram(self, s, t): - s = collections.Counter(s) - t = collections.Counter(t) - return s == t - -# 排序 -class Solution(object): - def isAnagram(self, s, t): +# 使用字典,判断两个字符串中字符的个数是否相同 +class Solution(object): + def isAnagram(self, s, t): + s = collections.Counter(s) + t = collections.Counter(t) + return s == t + +# 排序 +class Solution(object): + def isAnagram(self, s, t): return sorted(s) == sorted(t) \ No newline at end of file diff --git "a/leetcode/257.\344\272\214\345\217\211\346\240\221\347\232\204\346\211\200\346\234\211\350\267\257\345\276\204.py" "b/leetcode_Python/257.\344\272\214\345\217\211\346\240\221\347\232\204\346\211\200\346\234\211\350\267\257\345\276\204.py" similarity index 97% rename from "leetcode/257.\344\272\214\345\217\211\346\240\221\347\232\204\346\211\200\346\234\211\350\267\257\345\276\204.py" rename to "leetcode_Python/257.\344\272\214\345\217\211\346\240\221\347\232\204\346\211\200\346\234\211\350\267\257\345\276\204.py" index 7d720c6..a55ddf8 100644 --- "a/leetcode/257.\344\272\214\345\217\211\346\240\221\347\232\204\346\211\200\346\234\211\350\267\257\345\276\204.py" +++ "b/leetcode_Python/257.\344\272\214\345\217\211\346\240\221\347\232\204\346\211\200\346\234\211\350\267\257\345\276\204.py" @@ -1,20 +1,20 @@ -# 递归添加结点,到达叶结点时将该路径添加到res数组中 -class Solution(object): - def binaryTreePaths(self, root): - - def findPath(node, cur_path): - if not node: - return [] - if not node.left and not node.right: - res.append(cur_path + [node.val]) - return - if node.left: - findPath(node.left, cur_path + [node.val]) - if node.right: - findPath(node.right, cur_path + [node.val]) - - res = [] - if not root: - return res - findPath(root, []) +# 递归添加结点,到达叶结点时将该路径添加到res数组中 +class Solution(object): + def binaryTreePaths(self, root): + + def findPath(node, cur_path): + if not node: + return [] + if not node.left and not node.right: + res.append(cur_path + [node.val]) + return + if node.left: + findPath(node.left, cur_path + [node.val]) + if node.right: + findPath(node.right, cur_path + [node.val]) + + res = [] + if not root: + return res + findPath(root, []) return ['->'.join(str(val) for val in path) for path in res] \ No newline at end of file diff --git "a/leetcode/258.\345\220\204\344\275\215\347\233\270\345\212\240.py" "b/leetcode_Python/258.\345\220\204\344\275\215\347\233\270\345\212\240.py" similarity index 98% rename from "leetcode/258.\345\220\204\344\275\215\347\233\270\345\212\240.py" rename to "leetcode_Python/258.\345\220\204\344\275\215\347\233\270\345\212\240.py" index 6be2a60..308cfa4 100644 --- "a/leetcode/258.\345\220\204\344\275\215\347\233\270\345\212\240.py" +++ "b/leetcode_Python/258.\345\220\204\344\275\215\347\233\270\345\212\240.py" @@ -1,6 +1,6 @@ -# 将字符串拆成当个数字相加,判断结果长度是否大于1,循环此过程 -class Solution(object): - def addDigits(self, num): - while len(str(num)) > 1: - num = sum(map(int, [i for i in str(num)])) +# 将字符串拆成当个数字相加,判断结果长度是否大于1,循环此过程 +class Solution(object): + def addDigits(self, num): + while len(str(num)) > 1: + num = sum(map(int, [i for i in str(num)])) return num \ No newline at end of file diff --git "a/leetcode/263.\344\270\221\346\225\260.py" "b/leetcode_Python/263.\344\270\221\346\225\260.py" similarity index 96% rename from "leetcode/263.\344\270\221\346\225\260.py" rename to "leetcode_Python/263.\344\270\221\346\225\260.py" index ced3d4c..210099c 100644 --- "a/leetcode/263.\344\270\221\346\225\260.py" +++ "b/leetcode_Python/263.\344\270\221\346\225\260.py" @@ -1,12 +1,12 @@ -# 丑数只包含质因数 2, 3, 5,将质因数除尽看结果是否为1 -class Solution(object): - def isUgly(self, num): - if num <= 0: - return False - while num%2 == 0: - num /= 2 - while num%3 == 0: - num /= 3 - while num%5 == 0: - num /= 5 +# 丑数只包含质因数 2, 3, 5,将质因数除尽看结果是否为1 +class Solution(object): + def isUgly(self, num): + if num <= 0: + return False + while num%2 == 0: + num /= 2 + while num%3 == 0: + num /= 3 + while num%5 == 0: + num /= 5 return num == 1 \ No newline at end of file diff --git "a/leetcode/264.\344\270\221\346\225\260 II.py" "b/leetcode_Python/264.\344\270\221\346\225\260 II.py" similarity index 97% rename from "leetcode/264.\344\270\221\346\225\260 II.py" rename to "leetcode_Python/264.\344\270\221\346\225\260 II.py" index e83d94b..160ae63 100644 --- "a/leetcode/264.\344\270\221\346\225\260 II.py" +++ "b/leetcode_Python/264.\344\270\221\346\225\260 II.py" @@ -1,15 +1,15 @@ -# 使用三指针,当命中下一个丑数时,说明该指针指向的丑数乘以对应权重所得积最小,此时该指针应该指向下一个丑数 -# 使用三个并列的if让符合条件的指针都指向一个更大的数 -class Solution(object): - def nthUglyNumber(self, n): - res = [1] - idx2 = idx3 = idx5 = 0 - for i in range(n-1): - res.append(min(res[idx2]*2, res[idx3]*3, res[idx5]*5)) - if res[-1] == res[idx2]*2: - idx2 += 1 - if res[-1] == res[idx3]*3: - idx3 += 1 - if res[-1] == res[idx5]*5: - idx5 += 1 +# 使用三指针,当命中下一个丑数时,说明该指针指向的丑数乘以对应权重所得积最小,此时该指针应该指向下一个丑数 +# 使用三个并列的if让符合条件的指针都指向一个更大的数 +class Solution(object): + def nthUglyNumber(self, n): + res = [1] + idx2 = idx3 = idx5 = 0 + for i in range(n-1): + res.append(min(res[idx2]*2, res[idx3]*3, res[idx5]*5)) + if res[-1] == res[idx2]*2: + idx2 += 1 + if res[-1] == res[idx3]*3: + idx3 += 1 + if res[-1] == res[idx5]*5: + idx5 += 1 return res[-1] \ No newline at end of file diff --git "a/leetcode/268.\347\274\272\345\244\261\346\225\260\345\255\227.py" "b/leetcode_Python/268.\347\274\272\345\244\261\346\225\260\345\255\227.py" similarity index 97% rename from "leetcode/268.\347\274\272\345\244\261\346\225\260\345\255\227.py" rename to "leetcode_Python/268.\347\274\272\345\244\261\346\225\260\345\255\227.py" index 501144c..e154aae 100644 --- "a/leetcode/268.\347\274\272\345\244\261\346\225\260\345\255\227.py" +++ "b/leetcode_Python/268.\347\274\272\345\244\261\346\225\260\345\255\227.py" @@ -1,10 +1,10 @@ -# 方法一:求出差集 -class Solution(object): - def missingNumber(self, nums): - nums2 = [i for i in range(len(nums)+1)] - return int(list(set(nums2).difference(set(nums)))[0]) - -# 方法二:等差数列前n项和:n(n-1)/2 -class Solution(object): - def missingNumber(self, nums): +# 方法一:求出差集 +class Solution(object): + def missingNumber(self, nums): + nums2 = [i for i in range(len(nums)+1)] + return int(list(set(nums2).difference(set(nums)))[0]) + +# 方法二:等差数列前n项和:n(n-1)/2 +class Solution(object): + def missingNumber(self, nums): return len(nums) * (len(nums) + 1) / 2 - sum(nums) \ No newline at end of file diff --git "a/leetcode/278.\347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.py" "b/leetcode_Python/278.\347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.py" similarity index 97% rename from "leetcode/278.\347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.py" rename to "leetcode_Python/278.\347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.py" index 037a897..9921e77 100644 --- "a/leetcode/278.\347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.py" +++ "b/leetcode_Python/278.\347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.py" @@ -1,11 +1,11 @@ -# 二分法,取中间版本进行判断,若是好版本则将左起始点设为中间版本之后,若是坏版本则将右起始点设为为中间版本 -class Solution(object): - def firstBadVersion(self, n): - l, r = 1, n - while l < r: - mid = (l+r)/2 - if isBadVersion(mid): - r = mid - else: - l = mid + 1 - return l +# 二分法,取中间版本进行判断,若是好版本则将左起始点设为中间版本之后,若是坏版本则将右起始点设为为中间版本 +class Solution(object): + def firstBadVersion(self, n): + l, r = 1, n + while l < r: + mid = (l+r)/2 + if isBadVersion(mid): + r = mid + else: + l = mid + 1 + return l diff --git "a/leetcode/283.\347\247\273\345\212\250\351\233\266.py" "b/leetcode_Python/283.\347\247\273\345\212\250\351\233\266.py" similarity index 97% rename from "leetcode/283.\347\247\273\345\212\250\351\233\266.py" rename to "leetcode_Python/283.\347\247\273\345\212\250\351\233\266.py" index 96b1451..14c8d99 100644 --- "a/leetcode/283.\347\247\273\345\212\250\351\233\266.py" +++ "b/leetcode_Python/283.\347\247\273\345\212\250\351\233\266.py" @@ -1,11 +1,11 @@ -# 先将非0元素按顺序赋值到数组前,最后再补0 -class Solution(object): - def moveZeroes(self, nums): - j = 0 - for i in range(len(nums)): - if nums[i] != 0: - nums[j] = nums[i] - j += 1 - while j < len(nums): - nums[j] = 0 +# 先将非0元素按顺序赋值到数组前,最后再补0 +class Solution(object): + def moveZeroes(self, nums): + j = 0 + for i in range(len(nums)): + if nums[i] != 0: + nums[j] = nums[i] + j += 1 + while j < len(nums): + nums[j] = 0 j += 1 \ No newline at end of file diff --git "a/leetcode/290.\345\215\225\350\257\215\346\250\241\345\274\217.py" "b/leetcode_Python/290.\345\215\225\350\257\215\346\250\241\345\274\217.py" similarity index 98% rename from "leetcode/290.\345\215\225\350\257\215\346\250\241\345\274\217.py" rename to "leetcode_Python/290.\345\215\225\350\257\215\346\250\241\345\274\217.py" index 275ed64..fe2d16e 100644 --- "a/leetcode/290.\345\215\225\350\257\215\346\250\241\345\274\217.py" +++ "b/leetcode_Python/290.\345\215\225\350\257\215\346\250\241\345\274\217.py" @@ -1,7 +1,7 @@ -# 判断字符串、列表去重 与 压缩再去重的长度是否相同 -class Solution(object): - def wordPattern(self, pattern, str): - s = str.split() - if len(pattern) != len(s): - return False +# 判断字符串、列表去重 与 压缩再去重的长度是否相同 +class Solution(object): + def wordPattern(self, pattern, str): + s = str.split() + if len(pattern) != len(s): + return False return len(set(zip(pattern, s))) == len(set(pattern)) == len(set(s)) \ No newline at end of file diff --git "a/leetcode/292.Nim\346\270\270\346\210\217.py" "b/leetcode_Python/292.Nim\346\270\270\346\210\217.py" similarity index 97% rename from "leetcode/292.Nim\346\270\270\346\210\217.py" rename to "leetcode_Python/292.Nim\346\270\270\346\210\217.py" index 723e5e4..6b1b39a 100644 --- "a/leetcode/292.Nim\346\270\270\346\210\217.py" +++ "b/leetcode_Python/292.Nim\346\270\270\346\210\217.py" @@ -1,4 +1,4 @@ -# 只要给对手留下4的整数倍个石子就能赢,否则就输 -class Solution(object): - def canWinNim(self, n): +# 只要给对手留下4的整数倍个石子就能赢,否则就输 +class Solution(object): + def canWinNim(self, n): return n%4 != 0 \ No newline at end of file diff --git "a/leetcode/297.\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\344\270\216\345\217\215\345\272\217\345\210\227\345\214\226.py" "b/leetcode_Python/297.\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\344\270\216\345\217\215\345\272\217\345\210\227\345\214\226.py" similarity index 96% rename from "leetcode/297.\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\344\270\216\345\217\215\345\272\217\345\210\227\345\214\226.py" rename to "leetcode_Python/297.\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\344\270\216\345\217\215\345\272\217\345\210\227\345\214\226.py" index 0b83772..36bf6ff 100644 --- "a/leetcode/297.\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\344\270\216\345\217\215\345\272\217\345\210\227\345\214\226.py" +++ "b/leetcode_Python/297.\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\344\270\216\345\217\215\345\272\217\345\210\227\345\214\226.py" @@ -1,52 +1,52 @@ -# 方法一 -class Codec: - def __init__(self): - self.flag = -1 - - def serialize(self, root): - if not root: - return '#,' - return str(root.val) + ',' + self.serialize(root.left) + self.serialize(root.right) - - def deserialize(self, data): - self.flag += 1 - l = data.split(',') - if l[self.flag] == '#': - return - root = TreeNode(int(l[self.flag])) - root.left = self.deserialize(data) - root.right = self.deserialize(data) - return root - -# 方法二 -class Codec: - - def serialize(self, root): - def preorder(root): - if root: - result.append(str(root.val)) - preorder(root.left) - preorder(root.right) - else: - result.append("#") - result = [] - preorder(root) - return ','.join(result) - - def deserialize(self, data): - - def change(num): - num[0] += 1 - if num[0] < len(s): - if s[num[0]] == "#": - return None - root = TreeNode(int(s[num[0]])) - root.left = change(num) - root.right = change(num) - return root - else: - return None - - s = data.split(',') - num = [-1] +# 方法一 +class Codec: + def __init__(self): + self.flag = -1 + + def serialize(self, root): + if not root: + return '#,' + return str(root.val) + ',' + self.serialize(root.left) + self.serialize(root.right) + + def deserialize(self, data): + self.flag += 1 + l = data.split(',') + if l[self.flag] == '#': + return + root = TreeNode(int(l[self.flag])) + root.left = self.deserialize(data) + root.right = self.deserialize(data) + return root + +# 方法二 +class Codec: + + def serialize(self, root): + def preorder(root): + if root: + result.append(str(root.val)) + preorder(root.left) + preorder(root.right) + else: + result.append("#") + result = [] + preorder(root) + return ','.join(result) + + def deserialize(self, data): + + def change(num): + num[0] += 1 + if num[0] < len(s): + if s[num[0]] == "#": + return None + root = TreeNode(int(s[num[0]])) + root.left = change(num) + root.right = change(num) + return root + else: + return None + + s = data.split(',') + num = [-1] return change(num) \ No newline at end of file diff --git "a/leetcode/300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" "b/leetcode_Python/300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" similarity index 97% rename from "leetcode/300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" rename to "leetcode_Python/300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" index d6f590b..3337f87 100644 --- "a/leetcode/300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" +++ "b/leetcode_Python/300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" @@ -1,14 +1,14 @@ -# dp[i] 表示以 nums[i] 结尾的最长上升子序列的长度 -# nums:[10, 9, 2, 5, 3, 7, 101, 18] 为例: -# dp: [1, 1, 1, 2, 2, 3, 4, 4] -class Solution(object): - def lengthOfLIS(self, nums): - n = len(nums) - if n < 2: - return n - dp = [1]*n - for i in range(1, n): - for j in range(i): - if nums[i] > nums[j]: - dp[i] = max(dp[i], dp[j]+1) +# dp[i] 表示以 nums[i] 结尾的最长上升子序列的长度 +# nums:[10, 9, 2, 5, 3, 7, 101, 18] 为例: +# dp: [1, 1, 1, 2, 2, 3, 4, 4] +class Solution(object): + def lengthOfLIS(self, nums): + n = len(nums) + if n < 2: + return n + dp = [1]*n + for i in range(1, n): + for j in range(i): + if nums[i] > nums[j]: + dp[i] = max(dp[i], dp[j]+1) return max(dp) \ No newline at end of file diff --git "a/leetcode/303.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242-\346\225\260\347\273\204\344\270\215\345\217\257\345\217\230.py" "b/leetcode_Python/303.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242-\346\225\260\347\273\204\344\270\215\345\217\257\345\217\230.py" similarity index 95% rename from "leetcode/303.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242-\346\225\260\347\273\204\344\270\215\345\217\257\345\217\230.py" rename to "leetcode_Python/303.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242-\346\225\260\347\273\204\344\270\215\345\217\257\345\217\230.py" index 971b7d2..bf10771 100644 --- "a/leetcode/303.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242-\346\225\260\347\273\204\344\270\215\345\217\257\345\217\230.py" +++ "b/leetcode_Python/303.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242-\346\225\260\347\273\204\344\270\215\345\217\257\345\217\230.py" @@ -1,21 +1,21 @@ -# 方法一:数组切片 -class NumArray(object): - - def __init__(self, nums): - self.nums = nums - - def sumRange(self, i, j): - return sum(self.nums[i:j+1]) - -# 方法二:数组内先求和 -class NumArray(object): - - def __init__(self, nums): - self.nums = nums - for i in range(1, len(nums)): - self.nums[i] += self.nums[i-1] - - def sumRange(self, i, j): - if i==0: - return self.nums[j] - return self.nums[j]-self.nums[i-1] +# 方法一:数组切片 +class NumArray(object): + + def __init__(self, nums): + self.nums = nums + + def sumRange(self, i, j): + return sum(self.nums[i:j+1]) + +# 方法二:数组内先求和 +class NumArray(object): + + def __init__(self, nums): + self.nums = nums + for i in range(1, len(nums)): + self.nums[i] += self.nums[i-1] + + def sumRange(self, i, j): + if i==0: + return self.nums[j] + return self.nums[j]-self.nums[i-1] diff --git "a/leetcode/307.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242 - \346\225\260\347\273\204\345\217\257\344\277\256\346\224\271.py" "b/leetcode_Python/307.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242 - \346\225\260\347\273\204\345\217\257\344\277\256\346\224\271.py" similarity index 97% rename from "leetcode/307.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242 - \346\225\260\347\273\204\345\217\257\344\277\256\346\224\271.py" rename to "leetcode_Python/307.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242 - \346\225\260\347\273\204\345\217\257\344\277\256\346\224\271.py" index 236dec8..5f30cc0 100644 --- "a/leetcode/307.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242 - \346\225\260\347\273\204\345\217\257\344\277\256\346\224\271.py" +++ "b/leetcode_Python/307.\345\214\272\345\237\237\345\222\214\346\243\200\347\264\242 - \346\225\260\347\273\204\345\217\257\344\277\256\346\224\271.py" @@ -1,95 +1,95 @@ -# 树状数组 -class FenwickTree: - def __init__(self, n): - # 树状数组,从索引1开始存储,方便二进制计算 - self.C = [0 for _ in range(n+1)] - - def lowbit(self, x): - # 等价于 x and (x xor (x-1)) - # -x 由 x 的二进制每一位取反再加1得到 - # 最终结果表示x二进制最低位1代表的值 - return x & -x - - # C[i]=A[i-2^k+1]+A[i-2^k+2]+...+A[i]; k表示i的二进制最低位连续0的个数 - # C[i]=A[i-lowbit(i)+1]+A[i-lowbit(i)+2]+...+A[i]; - # i+lowbit(i)可得到结点i的父节点,i-lowbit(i)可得到上一区间的尾结点 - def update(self, i, val): - while i < len(self.C): - # 当前结点值更新 - self.C[i] += val - # 得到父节点 - i += self.lowbit(i) - - # 求原数组索引区间[0, i-1]元素之和。原数组索引从0开始 - def query(self, i): - res = 0 - while i > 0: - # 加上当前区间的和 - res += self.C[i] - # 得到上一区间的尾结点 - i -= self.lowbit(i) - return res - -class NumArray(object): - def __init__(self, nums): - self.nums = nums - self.tree = FenwickTree(len(nums)) - for i in range(len(nums)): - self.tree.update(i+1, nums[i]) - - def update(self, i, val): - self.tree.update(i+1, val-self.nums[i]) - self.nums[i] = val - - def sumRange(self, i, j): - return self.tree.query(j+1) - self.tree.query(i) - - - -# 线段树 -class NumArray2(object): - def __init__(self, nums): - # 取3倍长度 - self.value = [0]*len(nums)*3 - self.len = len(nums)-1 - if self.len >= 0: - self.buildTree(nums, 0, 0, self.len) - - def update(self, i, val): - self.updateTree(0, 0, self.len, i, val) - - def sumRange(self, i, j): - return self.sumRangeTree(0, 0, self.len, i, j) - - # 构造线段树 - def buildTree(self, nums, pos, l, r): - # 叶子节点 - if l == r: - self.value[pos] = nums[l] - return - mid = (l+r)//2 - self.buildTree(nums, pos*2+1, l, mid) - self.buildTree(nums, pos*2+2, mid+1, r) - # 当前结点值等于左结点的值加右节点的值 - self.value[pos] = self.value[pos*2+1] + self.value[pos*2+2] - - # 对指定区间求和 - def sumRangeTree(self, pos, l, r, ql, qr): - if ql > r or qr < l: - return 0 - if ql <= l and qr >= r: - return self.value[pos] - mid = (l+r)//2 - return self.sumRangeTree(pos*2+1, l, mid, ql, qr) + self.sumRangeTree(pos*2+2, mid+1, r, ql, qr) - - # 更新线段树 - def updateTree(self, pos, l, r, index, newval): - if l == r and l == index: - self.value[pos] = newval - return - mid = (l+r)//2 - if index <= mid: - self.updateTree(pos*2+1, l, mid, index, newval) - else: - self.updateTree(pos*2+2, mid+1, r, index, newval) +# 树状数组 +class FenwickTree: + def __init__(self, n): + # 树状数组,从索引1开始存储,方便二进制计算 + self.C = [0 for _ in range(n+1)] + + def lowbit(self, x): + # 等价于 x and (x xor (x-1)) + # -x 由 x 的二进制每一位取反再加1得到 + # 最终结果表示x二进制最低位1代表的值 + return x & -x + + # C[i]=A[i-2^k+1]+A[i-2^k+2]+...+A[i]; k表示i的二进制最低位连续0的个数 + # C[i]=A[i-lowbit(i)+1]+A[i-lowbit(i)+2]+...+A[i]; + # i+lowbit(i)可得到结点i的父节点,i-lowbit(i)可得到上一区间的尾结点 + def update(self, i, val): + while i < len(self.C): + # 当前结点值更新 + self.C[i] += val + # 得到父节点 + i += self.lowbit(i) + + # 求原数组索引区间[0, i-1]元素之和。原数组索引从0开始 + def query(self, i): + res = 0 + while i > 0: + # 加上当前区间的和 + res += self.C[i] + # 得到上一区间的尾结点 + i -= self.lowbit(i) + return res + +class NumArray(object): + def __init__(self, nums): + self.nums = nums + self.tree = FenwickTree(len(nums)) + for i in range(len(nums)): + self.tree.update(i+1, nums[i]) + + def update(self, i, val): + self.tree.update(i+1, val-self.nums[i]) + self.nums[i] = val + + def sumRange(self, i, j): + return self.tree.query(j+1) - self.tree.query(i) + + + +# 线段树 +class NumArray2(object): + def __init__(self, nums): + # 取3倍长度 + self.value = [0]*len(nums)*3 + self.len = len(nums)-1 + if self.len >= 0: + self.buildTree(nums, 0, 0, self.len) + + def update(self, i, val): + self.updateTree(0, 0, self.len, i, val) + + def sumRange(self, i, j): + return self.sumRangeTree(0, 0, self.len, i, j) + + # 构造线段树 + def buildTree(self, nums, pos, l, r): + # 叶子节点 + if l == r: + self.value[pos] = nums[l] + return + mid = (l+r)//2 + self.buildTree(nums, pos*2+1, l, mid) + self.buildTree(nums, pos*2+2, mid+1, r) + # 当前结点值等于左结点的值加右节点的值 + self.value[pos] = self.value[pos*2+1] + self.value[pos*2+2] + + # 对指定区间求和 + def sumRangeTree(self, pos, l, r, ql, qr): + if ql > r or qr < l: + return 0 + if ql <= l and qr >= r: + return self.value[pos] + mid = (l+r)//2 + return self.sumRangeTree(pos*2+1, l, mid, ql, qr) + self.sumRangeTree(pos*2+2, mid+1, r, ql, qr) + + # 更新线段树 + def updateTree(self, pos, l, r, index, newval): + if l == r and l == index: + self.value[pos] = newval + return + mid = (l+r)//2 + if index <= mid: + self.updateTree(pos*2+1, l, mid, index, newval) + else: + self.updateTree(pos*2+2, mid+1, r, index, newval) self.value[pos] = self.value[pos*2+1] + self.value[pos*2+2] \ No newline at end of file diff --git "a/leetcode/315.\350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.py" "b/leetcode_Python/315.\350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.py" similarity index 96% rename from "leetcode/315.\350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.py" rename to "leetcode_Python/315.\350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.py" index bf0b505..e710682 100644 --- "a/leetcode/315.\350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.py" +++ "b/leetcode_Python/315.\350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.py" @@ -1,107 +1,107 @@ -# 从右往左获取元素,则按序插入的索引即为右边比它小的元素个数 -# bisect_left获取待插入位置的索引,res存放该索引,seen存放排序的元素 -class Solution(object): - def countSmaller(self, nums): - res, seen = [], [] - for num in nums[::-1]: - index = bisect.bisect_left(seen, num) - res.append(index) - seen.insert(index, num) - return res[::-1] - - - -# 暴力,超时 -class Solution2(object): - def countSmaller(self, nums): - res = [] - for i in range(len(nums)): - count = 0 - for j in range(i, len(nums)): - if nums[i] > nums[j]: - count += 1 - res.append(count) - return res - - - -# 二叉搜索树 -class TreeNode(object): - def __init__(self, val): - self.left = None - self.right = None - self.val = val - # 左子树结点个数 - self.count = 0 - -class Solution3(object): - def countSmaller(self, nums): - n = len(nums) - root = None - res = [0 for _ in range(n)] - # 元素从右往左插入树,则可直接判断数组右侧小于当前元素的个数 - for i in reversed(range(n)): - # 当前元素构造完成后得到根结点,再递归插入下一元素 - root = self.insertNode(root, nums[i], res, i) - return res - - def insertNode(self, root, val, res, res_index): - # 若结点为空,则根据传入值构造结点 - if not root: - root = TreeNode(val) - elif val <= root.val: - root.count += 1 - root.left = self.insertNode(root.left, val, res, res_index) - elif val > root.val: - # 统计右侧小于当前元素的个数,即左子树结点个数和根结点 - res[res_index] += root.count + 1 - root.right = self.insertNode(root.right, val, res, res_index) - # 当前元素插入树中后返回根结点 - return root - - - -# 树状数组 -class Solution4(object): - def countSmaller(self, nums): - def lowbit(x): - # 等价于 x and (x xor (x-1)) - # -x 由 x 的二进制每一位取反再加1得到 - # 最终结果表示x二进制最低位1代表的值 - return x & -x - - # C[i]=A[i-2^k+1]+A[i-2^k+2]+...+A[i]; k表示i的二进制最低位连续0的个数 - # C[i]=A[i-lowbit(i)+1]+A[i-lowbit(i)+2]+...+A[i]; - # i+lowbit(i)可得到结点i的父节点,i-lowbit(i)可得到上一区间的尾结点 - def update(i, val, c): - while i < len(c): - # 当前结点值更新 - c[i] += val - # 得到父节点 - i += lowbit(i) - - def getSum(i, c): - ans = 0 - while i > 0: - # 加上当前区间的和 - ans += c[i] - # 得到上一区间的尾结点 - i -= lowbit(i) - return ans - - new_nums = sorted(set(nums)) - d = {} - for i in range(len(new_nums)): - d[new_nums[i]] = i - - res = [] - l = len(new_nums) - a = [0 for _ in range(l)] - c = [0 for _ in range(l+1)] - for i in range(len(nums)-1, -1, -1): - num = d[nums[i]] - a[num] += 1 - update(num+1, 1, c) - res.append(getSum(num, c)) - +# 从右往左获取元素,则按序插入的索引即为右边比它小的元素个数 +# bisect_left获取待插入位置的索引,res存放该索引,seen存放排序的元素 +class Solution(object): + def countSmaller(self, nums): + res, seen = [], [] + for num in nums[::-1]: + index = bisect.bisect_left(seen, num) + res.append(index) + seen.insert(index, num) + return res[::-1] + + + +# 暴力,超时 +class Solution2(object): + def countSmaller(self, nums): + res = [] + for i in range(len(nums)): + count = 0 + for j in range(i, len(nums)): + if nums[i] > nums[j]: + count += 1 + res.append(count) + return res + + + +# 二叉搜索树 +class TreeNode(object): + def __init__(self, val): + self.left = None + self.right = None + self.val = val + # 左子树结点个数 + self.count = 0 + +class Solution3(object): + def countSmaller(self, nums): + n = len(nums) + root = None + res = [0 for _ in range(n)] + # 元素从右往左插入树,则可直接判断数组右侧小于当前元素的个数 + for i in reversed(range(n)): + # 当前元素构造完成后得到根结点,再递归插入下一元素 + root = self.insertNode(root, nums[i], res, i) + return res + + def insertNode(self, root, val, res, res_index): + # 若结点为空,则根据传入值构造结点 + if not root: + root = TreeNode(val) + elif val <= root.val: + root.count += 1 + root.left = self.insertNode(root.left, val, res, res_index) + elif val > root.val: + # 统计右侧小于当前元素的个数,即左子树结点个数和根结点 + res[res_index] += root.count + 1 + root.right = self.insertNode(root.right, val, res, res_index) + # 当前元素插入树中后返回根结点 + return root + + + +# 树状数组 +class Solution4(object): + def countSmaller(self, nums): + def lowbit(x): + # 等价于 x and (x xor (x-1)) + # -x 由 x 的二进制每一位取反再加1得到 + # 最终结果表示x二进制最低位1代表的值 + return x & -x + + # C[i]=A[i-2^k+1]+A[i-2^k+2]+...+A[i]; k表示i的二进制最低位连续0的个数 + # C[i]=A[i-lowbit(i)+1]+A[i-lowbit(i)+2]+...+A[i]; + # i+lowbit(i)可得到结点i的父节点,i-lowbit(i)可得到上一区间的尾结点 + def update(i, val, c): + while i < len(c): + # 当前结点值更新 + c[i] += val + # 得到父节点 + i += lowbit(i) + + def getSum(i, c): + ans = 0 + while i > 0: + # 加上当前区间的和 + ans += c[i] + # 得到上一区间的尾结点 + i -= lowbit(i) + return ans + + new_nums = sorted(set(nums)) + d = {} + for i in range(len(new_nums)): + d[new_nums[i]] = i + + res = [] + l = len(new_nums) + a = [0 for _ in range(l)] + c = [0 for _ in range(l+1)] + for i in range(len(nums)-1, -1, -1): + num = d[nums[i]] + a[num] += 1 + update(num+1, 1, c) + res.append(getSum(num, c)) + return res[::-1] \ No newline at end of file diff --git "a/leetcode/326.3\347\232\204\345\271\202.py" "b/leetcode_Python/326.3\347\232\204\345\271\202.py" similarity index 97% rename from "leetcode/326.3\347\232\204\345\271\202.py" rename to "leetcode_Python/326.3\347\232\204\345\271\202.py" index 1bb26d3..0737ae7 100644 --- "a/leetcode/326.3\347\232\204\345\271\202.py" +++ "b/leetcode_Python/326.3\347\232\204\345\271\202.py" @@ -1,8 +1,8 @@ -# 因子可全由3组成,除尽3判断最终结果是否等于1 -class Solution(object): - def isPowerOfThree(self, n): - if n==0: - return False - while n%3 == 0: - n /= 3 +# 因子可全由3组成,除尽3判断最终结果是否等于1 +class Solution(object): + def isPowerOfThree(self, n): + if n==0: + return False + while n%3 == 0: + n /= 3 return n == 1 \ No newline at end of file diff --git "a/leetcode/328.\345\245\207\345\201\266\351\223\276\350\241\250.py" "b/leetcode_Python/328.\345\245\207\345\201\266\351\223\276\350\241\250.py" similarity index 97% rename from "leetcode/328.\345\245\207\345\201\266\351\223\276\350\241\250.py" rename to "leetcode_Python/328.\345\245\207\345\201\266\351\223\276\350\241\250.py" index e81476a..699e710 100644 --- "a/leetcode/328.\345\245\207\345\201\266\351\223\276\350\241\250.py" +++ "b/leetcode_Python/328.\345\245\207\345\201\266\351\223\276\350\241\250.py" @@ -1,13 +1,13 @@ -# 依赖next指针,奇偶位置的结点交替连接,最后奇偶链连接 -class Solution(object): - def oddEvenList(self, head): - if not head: - return head - odd, even, evenHead = head, head.next, head.next - while even and even.next: - odd.next = even.next - odd = odd.next - even.next = odd.next - even = even.next - odd.next = evenHead +# 依赖next指针,奇偶位置的结点交替连接,最后奇偶链连接 +class Solution(object): + def oddEvenList(self, head): + if not head: + return head + odd, even, evenHead = head, head.next, head.next + while even and even.next: + odd.next = even.next + odd = odd.next + even.next = odd.next + even = even.next + odd.next = evenHead return head \ No newline at end of file diff --git "a/leetcode/337.\346\211\223\345\256\266\345\212\253\350\210\215III.py" "b/leetcode_Python/337.\346\211\223\345\256\266\345\212\253\350\210\215III.py" similarity index 97% rename from "leetcode/337.\346\211\223\345\256\266\345\212\253\350\210\215III.py" rename to "leetcode_Python/337.\346\211\223\345\256\266\345\212\253\350\210\215III.py" index 32f0df8..79574b4 100644 --- "a/leetcode/337.\346\211\223\345\256\266\345\212\253\350\210\215III.py" +++ "b/leetcode_Python/337.\346\211\223\345\256\266\345\212\253\350\210\215III.py" @@ -1,30 +1,30 @@ -class Solution(object): - def rob(self, root): - - def dfs(root): - if not root: - return (0, 0) - l_rob, l_norob = dfs(root.left) - r_rob, r_norob = dfs(root.right) - cur_rob = l_norob + r_norob + root.val - # 当前结点不偷时,需要再判断子结点偷与不偷哪个更大 - cur_norob = max(l_rob, l_norob) + max(r_rob, r_norob) - return (cur_rob, cur_norob) - - return max(dfs(root)) - -##################### 递归思路 ####################### -# 方法作用极简化:先判断无结点和1个结点的情况 -# 方法作用描述:参数给一个结点,返回该结点偷与不偷的值 -# 递归:由于左右子树需要同样操作,使用递归。 -class Solution(object): - def rob(self, root): - - def dfs(root): - if not root: - return (0, 0) - cur_rob = root.val - cur_norob = 0 - return (cur_rob, cur_norob) - +class Solution(object): + def rob(self, root): + + def dfs(root): + if not root: + return (0, 0) + l_rob, l_norob = dfs(root.left) + r_rob, r_norob = dfs(root.right) + cur_rob = l_norob + r_norob + root.val + # 当前结点不偷时,需要再判断子结点偷与不偷哪个更大 + cur_norob = max(l_rob, l_norob) + max(r_rob, r_norob) + return (cur_rob, cur_norob) + + return max(dfs(root)) + +##################### 递归思路 ####################### +# 方法作用极简化:先判断无结点和1个结点的情况 +# 方法作用描述:参数给一个结点,返回该结点偷与不偷的值 +# 递归:由于左右子树需要同样操作,使用递归。 +class Solution(object): + def rob(self, root): + + def dfs(root): + if not root: + return (0, 0) + cur_rob = root.val + cur_norob = 0 + return (cur_rob, cur_norob) + return max(dfs(root)) \ No newline at end of file diff --git "a/leetcode/338.\346\257\224\347\211\271\344\275\215\350\256\241\346\225\260.py" "b/leetcode_Python/338.\346\257\224\347\211\271\344\275\215\350\256\241\346\225\260.py" similarity index 97% rename from "leetcode/338.\346\257\224\347\211\271\344\275\215\350\256\241\346\225\260.py" rename to "leetcode_Python/338.\346\257\224\347\211\271\344\275\215\350\256\241\346\225\260.py" index 7c83c50..d5482fc 100644 --- "a/leetcode/338.\346\257\224\347\211\271\344\275\215\350\256\241\346\225\260.py" +++ "b/leetcode_Python/338.\346\257\224\347\211\271\344\275\215\350\256\241\346\225\260.py" @@ -1,28 +1,28 @@ -# 计算二进制后直接统计'1'的个数 -class Solution(object): - def countBits(self, num): - res = [] - for i in range(num+1): - res.append(str(bin(i)).count('1')) - return res - -# 动态规划 -# i为偶数时,f(i)=f(i/2),因为i/2本质上是i的二进制左移一位,低位补零,所以1的数量不变 -# i为奇数时,f(i)=f(i-1)+1,因为i-1为偶数,而偶数的二进制最低位一定是0,偶数加1后最低位变为1且不会进位 -class Solution2(object): - def countBits(self, num): - res = [0] - for i in range(1, num+1): - if i%2 == 0: - res.append(res[i/2]) - else: - res.append(res[i-1]+1) - return res - -# “与”写法 -class Solution3(object): - def countBits(self, num): - res = [0] - for i in range(1, num+1): - res.append(res[i/2] + (i&1)) +# 计算二进制后直接统计'1'的个数 +class Solution(object): + def countBits(self, num): + res = [] + for i in range(num+1): + res.append(str(bin(i)).count('1')) + return res + +# 动态规划 +# i为偶数时,f(i)=f(i/2),因为i/2本质上是i的二进制左移一位,低位补零,所以1的数量不变 +# i为奇数时,f(i)=f(i-1)+1,因为i-1为偶数,而偶数的二进制最低位一定是0,偶数加1后最低位变为1且不会进位 +class Solution2(object): + def countBits(self, num): + res = [0] + for i in range(1, num+1): + if i%2 == 0: + res.append(res[i/2]) + else: + res.append(res[i-1]+1) + return res + +# “与”写法 +class Solution3(object): + def countBits(self, num): + res = [0] + for i in range(1, num+1): + res.append(res[i/2] + (i&1)) return res \ No newline at end of file diff --git "a/leetcode/342.4\347\232\204\345\271\202.py" "b/leetcode_Python/342.4\347\232\204\345\271\202.py" similarity index 97% rename from "leetcode/342.4\347\232\204\345\271\202.py" rename to "leetcode_Python/342.4\347\232\204\345\271\202.py" index d1345d1..7bbc1d5 100644 --- "a/leetcode/342.4\347\232\204\345\271\202.py" +++ "b/leetcode_Python/342.4\347\232\204\345\271\202.py" @@ -1,8 +1,8 @@ -# 因子可全由4组成,除尽4判断最终结果是否等于1 -class Solution(object): - def isPowerOfFour(self, num): - if num==0: - return False - while num%4 == 0: - num /= 4 +# 因子可全由4组成,除尽4判断最终结果是否等于1 +class Solution(object): + def isPowerOfFour(self, num): + if num==0: + return False + while num%4 == 0: + num /= 4 return num == 1 \ No newline at end of file diff --git "a/leetcode/344.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/344.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "leetcode/344.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/344.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.py" index a71d6fb..a35ce5b 100644 --- "a/leetcode/344.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/344.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.py" @@ -1,3 +1,3 @@ -class Solution(object): - def reverseString(self, s): +class Solution(object): + def reverseString(self, s): return s[::-1] \ No newline at end of file diff --git "a/leetcode/345.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.py" "b/leetcode_Python/345.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.py" similarity index 97% rename from "leetcode/345.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.py" rename to "leetcode_Python/345.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.py" index 732b1f1..df4af0d 100644 --- "a/leetcode/345.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.py" +++ "b/leetcode_Python/345.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.py" @@ -1,22 +1,22 @@ -# 方法一:利用左右索引寻找元音字符交换 -class Solution(object): - def reverseVowels(self, s): - list_s = list(s) - vowels = 'aeiouAEIOU' - l, r = 0, len(s)-1 - while l <= r: - if list_s[l] not in vowels: - l += 1 - elif list_s[r] not in vowels: - r -= 1 - else: - list_s[l], list_s[r] = list_s[r], list_s[l] - l += 1 - r -= 1 - return ''.join(list_s) - -# 方法二:正则表达式 -class Solution(object): - def reverseVowels(self, s): - vowels = re.findall(r'[aeiouAEIOU]', s) +# 方法一:利用左右索引寻找元音字符交换 +class Solution(object): + def reverseVowels(self, s): + list_s = list(s) + vowels = 'aeiouAEIOU' + l, r = 0, len(s)-1 + while l <= r: + if list_s[l] not in vowels: + l += 1 + elif list_s[r] not in vowels: + r -= 1 + else: + list_s[l], list_s[r] = list_s[r], list_s[l] + l += 1 + r -= 1 + return ''.join(list_s) + +# 方法二:正则表达式 +class Solution(object): + def reverseVowels(self, s): + vowels = re.findall(r'[aeiouAEIOU]', s) return re.sub('[aeiouAEIOU]', lambda m: vowels.pop(), s) \ No newline at end of file diff --git "a/leetcode/347.\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" "b/leetcode_Python/347.\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" similarity index 96% rename from "leetcode/347.\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" rename to "leetcode_Python/347.\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" index 4175453..fef3ce2 100644 --- "a/leetcode/347.\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" +++ "b/leetcode_Python/347.\345\211\215 K \344\270\252\351\253\230\351\242\221\345\205\203\347\264\240.py" @@ -1,11 +1,11 @@ -from collections import Counter -class Solution(object): - def topKFrequent(self, nums, k): - # {1: 3, 2: 2, 3: 1} → [(1, 3), (2, 2)] - return [item[0] for item in Counter(nums).most_common(k)] - -s = Solution() -nums = [1,1,1,2,2,3] -k = 2 -res = s.topKFrequent(nums, k) +from collections import Counter +class Solution(object): + def topKFrequent(self, nums, k): + # {1: 3, 2: 2, 3: 1} → [(1, 3), (2, 2)] + return [item[0] for item in Counter(nums).most_common(k)] + +s = Solution() +nums = [1,1,1,2,2,3] +k = 2 +res = s.topKFrequent(nums, k) print(res) \ No newline at end of file diff --git "a/leetcode/349.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.py" "b/leetcode_Python/349.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.py" similarity index 96% rename from "leetcode/349.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.py" rename to "leetcode_Python/349.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.py" index 9c73799..7ea9912 100644 --- "a/leetcode/349.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.py" +++ "b/leetcode_Python/349.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.py" @@ -1,13 +1,13 @@ -# 方法一 -class Solution(object): - def intersection(self, nums1, nums2): - res = [] - for i in set(nums1): - if i in nums2: - res.append(i) - return res - -# 方法二 -class Solution(object): - def intersection(self, nums1, nums2): +# 方法一 +class Solution(object): + def intersection(self, nums1, nums2): + res = [] + for i in set(nums1): + if i in nums2: + res.append(i) + return res + +# 方法二 +class Solution(object): + def intersection(self, nums1, nums2): return list(set(nums1).intersection(set(nums2))) \ No newline at end of file diff --git "a/leetcode/350.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206II.py" "b/leetcode_Python/350.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206II.py" similarity index 96% rename from "leetcode/350.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206II.py" rename to "leetcode_Python/350.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206II.py" index 3133de6..756c6f3 100644 --- "a/leetcode/350.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206II.py" +++ "b/leetcode_Python/350.\344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206II.py" @@ -1,10 +1,10 @@ -# 使用字典 -class Solution(object): - def intersect(self, nums1, nums2): - res = [] - d = collections.Counter(nums2) - for i in nums1: - if d[i] > 0: - res.append(i) - d[i] -= 1 +# 使用字典 +class Solution(object): + def intersect(self, nums1, nums2): + res = [] + d = collections.Counter(nums2) + for i in nums1: + if d[i] > 0: + res.append(i) + d[i] -= 1 return res \ No newline at end of file diff --git "a/leetcode/367.\346\234\211\346\225\210\347\232\204\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" "b/leetcode_Python/367.\346\234\211\346\225\210\347\232\204\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" similarity index 96% rename from "leetcode/367.\346\234\211\346\225\210\347\232\204\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" rename to "leetcode_Python/367.\346\234\211\346\225\210\347\232\204\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" index 0a9cb27..55f403c 100644 --- "a/leetcode/367.\346\234\211\346\225\210\347\232\204\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" +++ "b/leetcode_Python/367.\346\234\211\346\225\210\347\232\204\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" @@ -1,19 +1,19 @@ -# 方法一:直接平方根 -class Solution(object): - def isPerfectSquare(self, num): - return (num**0.5) == int(num**0.5) - -# 方法二:二分法,查找是否存在一个数的平方为给定的正整数 -class Solution(object): - def isPerfectSquare(self, num): - l, r = 0, num - while l <= r: - mid = (l+r)/2 - square = mid**2 - if square > num: - r = mid - 1 - elif square < num: - l = mid + 1 - else: - return True +# 方法一:直接平方根 +class Solution(object): + def isPerfectSquare(self, num): + return (num**0.5) == int(num**0.5) + +# 方法二:二分法,查找是否存在一个数的平方为给定的正整数 +class Solution(object): + def isPerfectSquare(self, num): + l, r = 0, num + while l <= r: + mid = (l+r)/2 + square = mid**2 + if square > num: + r = mid - 1 + elif square < num: + l = mid + 1 + else: + return True return False \ No newline at end of file diff --git "a/leetcode/371.\344\270\244\346\225\264\346\225\260\344\271\213\345\222\214.py" "b/leetcode_Python/371.\344\270\244\346\225\264\346\225\260\344\271\213\345\222\214.py" similarity index 97% rename from "leetcode/371.\344\270\244\346\225\264\346\225\260\344\271\213\345\222\214.py" rename to "leetcode_Python/371.\344\270\244\346\225\264\346\225\260\344\271\213\345\222\214.py" index 8db89cd..25a99ca 100644 --- "a/leetcode/371.\344\270\244\346\225\264\346\225\260\344\271\213\345\222\214.py" +++ "b/leetcode_Python/371.\344\270\244\346\225\264\346\225\260\344\271\213\345\222\214.py" @@ -1,3 +1,3 @@ -class Solution(object): - def getSum(self, a, b): +class Solution(object): + def getSum(self, a, b): return sum([a, b]) \ No newline at end of file diff --git "a/leetcode/374.\347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.py" "b/leetcode_Python/374.\347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.py" similarity index 96% rename from "leetcode/374.\347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.py" rename to "leetcode_Python/374.\347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.py" index 5e708cc..dc8cc55 100644 --- "a/leetcode/374.\347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.py" +++ "b/leetcode_Python/374.\347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.py" @@ -1,12 +1,12 @@ -# 根据返回结果重新定位左右区间 -class Solution(object): - def guessNumber(self, n): - l, r = 1, n - while l <= r: - mid = (l+r)/2 - if guess(mid) == -1: - r = mid - 1 - elif guess(mid) == 1: - l = mid + 1 - else: +# 根据返回结果重新定位左右区间 +class Solution(object): + def guessNumber(self, n): + l, r = 1, n + while l <= r: + mid = (l+r)/2 + if guess(mid) == -1: + r = mid - 1 + elif guess(mid) == 1: + l = mid + 1 + else: return mid \ No newline at end of file diff --git "a/leetcode/376.\346\221\206\345\212\250\345\272\217\345\210\227.py" "b/leetcode_Python/376.\346\221\206\345\212\250\345\272\217\345\210\227.py" similarity index 96% rename from "leetcode/376.\346\221\206\345\212\250\345\272\217\345\210\227.py" rename to "leetcode_Python/376.\346\221\206\345\212\250\345\272\217\345\210\227.py" index cb85acd..5de7166 100644 --- "a/leetcode/376.\346\221\206\345\212\250\345\272\217\345\210\227.py" +++ "b/leetcode_Python/376.\346\221\206\345\212\250\345\272\217\345\210\227.py" @@ -1,17 +1,17 @@ -# 贪心算法 -class Solution(object): - def wiggleMaxLength(self, nums): - # 边界条件 - n = len(nums) - if n < 2: - return n - - # 以正/负结尾时的最长摆动序列长度 - up = down = 1 - # 正负性相同则长度不变,相反则加1 - for i in range(1, n): - if nums[i-1] < nums[i]: - up = down + 1 - if nums[i-1] > nums[i]: - down = up + 1 +# 贪心算法 +class Solution(object): + def wiggleMaxLength(self, nums): + # 边界条件 + n = len(nums) + if n < 2: + return n + + # 以正/负结尾时的最长摆动序列长度 + up = down = 1 + # 正负性相同则长度不变,相反则加1 + for i in range(1, n): + if nums[i-1] < nums[i]: + up = down + 1 + if nums[i-1] > nums[i]: + down = up + 1 return max(up, down) \ No newline at end of file diff --git "a/leetcode/383.\350\265\216\351\207\221\344\277\241.py" "b/leetcode_Python/383.\350\265\216\351\207\221\344\277\241.py" similarity index 96% rename from "leetcode/383.\350\265\216\351\207\221\344\277\241.py" rename to "leetcode_Python/383.\350\265\216\351\207\221\344\277\241.py" index 46fa6a2..48ee9fd 100644 --- "a/leetcode/383.\350\265\216\351\207\221\344\277\241.py" +++ "b/leetcode_Python/383.\350\265\216\351\207\221\344\277\241.py" @@ -1,40 +1,40 @@ -# 方法一:使用正则表达式 -class Solution(object): - def canConstruct(self, ransomNote, magazine): - for char in ransomNote: - # 将magazine的char字符替换为空,且只能替换一次 - new_mag, num = re.subn(char, '', magazine, count=1) - magazine = new_mag - # 替换次数为0 - if not num: - return False - return True - -# 方法二:先统计字符的个数,再比较个数大小 -class Solution(object): - def canConstruct(self, ransomNote, magazine): - ranCounter = collections.Counter(ransomNote) - magCounter = collections.Counter(magazine) - for k in ranCounter: - if ranCounter.get(k) > magCounter.get(k): - return False - return True - -# 方法三:使用字典累加字符与个数,再逐一消减判断 -class Solution(object): - def canConstruct(self, ransomNote, magazine): - d = {} - for i in magazine: - if i not in d: - d[i] = 1 - else: - d[i] += 1 - - for i in ransomNote: - if i not in d: - return False - d[i] -= 1 - if d[i] < 0: - return False - +# 方法一:使用正则表达式 +class Solution(object): + def canConstruct(self, ransomNote, magazine): + for char in ransomNote: + # 将magazine的char字符替换为空,且只能替换一次 + new_mag, num = re.subn(char, '', magazine, count=1) + magazine = new_mag + # 替换次数为0 + if not num: + return False + return True + +# 方法二:先统计字符的个数,再比较个数大小 +class Solution(object): + def canConstruct(self, ransomNote, magazine): + ranCounter = collections.Counter(ransomNote) + magCounter = collections.Counter(magazine) + for k in ranCounter: + if ranCounter.get(k) > magCounter.get(k): + return False + return True + +# 方法三:使用字典累加字符与个数,再逐一消减判断 +class Solution(object): + def canConstruct(self, ransomNote, magazine): + d = {} + for i in magazine: + if i not in d: + d[i] = 1 + else: + d[i] += 1 + + for i in ransomNote: + if i not in d: + return False + d[i] -= 1 + if d[i] < 0: + return False + return True \ No newline at end of file diff --git "a/leetcode/387.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.py" "b/leetcode_Python/387.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.py" similarity index 96% rename from "leetcode/387.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.py" rename to "leetcode_Python/387.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.py" index a1cf9e5..52b9124 100644 --- "a/leetcode/387.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.py" +++ "b/leetcode_Python/387.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\347\254\254\344\270\200\344\270\252\345\224\257\344\270\200\345\255\227\347\254\246.py" @@ -1,9 +1,9 @@ -# 使用字典存放值与个数 -import collections -class Solution(object): - def firstUniqChar(self, s): - d = collections.Counter(s) - for i, v in enumerate(s): - if d[v] == 1: - return i +# 使用字典存放值与个数 +import collections +class Solution(object): + def firstUniqChar(self, s): + d = collections.Counter(s) + for i, v in enumerate(s): + if d[v] == 1: + return i return -1 \ No newline at end of file diff --git "a/leetcode/389.\346\211\276\344\270\215\345\220\214.py" "b/leetcode_Python/389.\346\211\276\344\270\215\345\220\214.py" similarity index 97% rename from "leetcode/389.\346\211\276\344\270\215\345\220\214.py" rename to "leetcode_Python/389.\346\211\276\344\270\215\345\220\214.py" index 158bf2c..fb8e0a9 100644 --- "a/leetcode/389.\346\211\276\344\270\215\345\220\214.py" +++ "b/leetcode_Python/389.\346\211\276\344\270\215\345\220\214.py" @@ -1,14 +1,14 @@ -# 方法一:遍历s,在t中移除遍历到的元素,最后剩下一个就是添加的字母 -class Solution(object): - def findTheDifference(self, s, t): - t = list(t) - for i in s: - t.remove(i) - return t[0] - -# 方法二:遍历t,统计t与s中该字符的个数,若不相同则为添加的字母 -class Solution(object): - def findTheDifference(self, s, t): - for i in t: - if t.count(i) != s.count(i): +# 方法一:遍历s,在t中移除遍历到的元素,最后剩下一个就是添加的字母 +class Solution(object): + def findTheDifference(self, s, t): + t = list(t) + for i in s: + t.remove(i) + return t[0] + +# 方法二:遍历t,统计t与s中该字符的个数,若不相同则为添加的字母 +class Solution(object): + def findTheDifference(self, s, t): + for i in t: + if t.count(i) != s.count(i): return i \ No newline at end of file diff --git "a/leetcode/390.\346\266\210\351\231\244\346\270\270\346\210\217.py" "b/leetcode_Python/390.\346\266\210\351\231\244\346\270\270\346\210\217.py" similarity index 96% rename from "leetcode/390.\346\266\210\351\231\244\346\270\270\346\210\217.py" rename to "leetcode_Python/390.\346\266\210\351\231\244\346\270\270\346\210\217.py" index e25d5de..814fd5e 100644 --- "a/leetcode/390.\346\266\210\351\231\244\346\270\270\346\210\217.py" +++ "b/leetcode_Python/390.\346\266\210\351\231\244\346\270\270\346\210\217.py" @@ -1,18 +1,18 @@ -# 按题目说明解法 -class Solution(object): - def lastRemaining(self, n): - nums = [i+1 for i in range(n)] - res = [] - while len(nums) > 1: - for i in range(1, len(nums), 2): - res.append(nums[i]) - nums, res = res[::-1], [] - return nums[0] - - -# 找规律,如果输入a输出b,则输入2a输出2*(a-b+1) -class Solution(object): - def lastRemaining(self, n): - if n == 1: - return 1 +# 按题目说明解法 +class Solution(object): + def lastRemaining(self, n): + nums = [i+1 for i in range(n)] + res = [] + while len(nums) > 1: + for i in range(1, len(nums), 2): + res.append(nums[i]) + nums, res = res[::-1], [] + return nums[0] + + +# 找规律,如果输入a输出b,则输入2a输出2*(a-b+1) +class Solution(object): + def lastRemaining(self, n): + if n == 1: + return 1 return 2 * (n/2 - self.lastRemaining(n/2) + 1) \ No newline at end of file diff --git "a/leetcode/395.\350\207\263\345\260\221\346\234\211K\344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" "b/leetcode_Python/395.\350\207\263\345\260\221\346\234\211K\344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" similarity index 97% rename from "leetcode/395.\350\207\263\345\260\221\346\234\211K\344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" rename to "leetcode_Python/395.\350\207\263\345\260\221\346\234\211K\344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" index ffedccd..27d3796 100644 --- "a/leetcode/395.\350\207\263\345\260\221\346\234\211K\344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" +++ "b/leetcode_Python/395.\350\207\263\345\260\221\346\234\211K\344\270\252\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" @@ -1,13 +1,13 @@ -# 分治法 -class Solution(object): - def longestSubstring(self, s, k): - if not s: - return 0 - # 遍历字符串去重后的字符 - for c in set(s): - # 如果字符个数少于k - if s.count(c) < k: - # 按照该字符拆分字符串,再递归求出拆分后的字串中最长的字串 - return max(self.longestSubstring(t, k) for t in s.split(c)) - # 每个字符的个数都大于等于k,则返回字符串的长度 +# 分治法 +class Solution(object): + def longestSubstring(self, s, k): + if not s: + return 0 + # 遍历字符串去重后的字符 + for c in set(s): + # 如果字符个数少于k + if s.count(c) < k: + # 按照该字符拆分字符串,再递归求出拆分后的字串中最长的字串 + return max(self.longestSubstring(t, k) for t in s.split(c)) + # 每个字符的个数都大于等于k,则返回字符串的长度 return len(s) \ No newline at end of file diff --git "a/leetcode/399.\351\231\244\346\263\225\346\261\202\345\200\274.py" "b/leetcode_Python/399.\351\231\244\346\263\225\346\261\202\345\200\274.py" similarity index 97% rename from "leetcode/399.\351\231\244\346\263\225\346\261\202\345\200\274.py" rename to "leetcode_Python/399.\351\231\244\346\263\225\346\261\202\345\200\274.py" index 3f86e65..ca0492a 100644 --- "a/leetcode/399.\351\231\244\346\263\225\346\261\202\345\200\274.py" +++ "b/leetcode_Python/399.\351\231\244\346\263\225\346\261\202\345\200\274.py" @@ -1,93 +1,93 @@ -# 首先要把除法运算转化成图表示,比如a->b = 2.0 b->c = 3.0, a,b,c看成节点,相除所得值为权值. -# 那么a/c = ? 就是相当于 a->c <==> a->b->c = 2.0*3.0 = 6,所以要把已知条件建图! - -# 深度优先搜索 -class Solution(object): - def calcEquation(self, equations, values, queries): - # 存放结点及其邻接点 - graph = collections.defaultdict(set) - # 存放每条边的权重 - weight = {} - # 构建图 - for index, equa in enumerate(equations): - graph[equa[0]].add(equa[1]) - graph[equa[1]].add(equa[0]) - weight[tuple(equa)] = values[index] - weight[(equa[1], equa[0])] = float(1 / values[index]) - - def dfs(start, end, visited): - # 图中有这条边,直接返回 - if (start, end) in weight: - return weight[(start, end)] - # 图中没有该结点 - if start not in graph or end not in graph: - return 0 - # 已经访问过 - if start in visited: - return 0 - # 当前结点正在访问 - visited.add(start) - w = 0 - # 深度优先遍历每个邻接点 - for temp in graph[start]: - w = (weight[(start, temp)] * dfs(temp, end, visited)) - # 遍历到一个可行解则退出 - if w != 0: - # 添加此边,以后访问节省时间 - weight[(start, end)] = w - break - # 访问完成 - visited.remove(start) - return w - - res = [] - for q in queries: - w = dfs(q[0], q[1], set()) - if w == 0: - w = -1.0 - res.append(w) - return res - - -# 广度优先搜索 -class Solution2(object): - def calcEquation(self, equations, values, queries): - graph = collections.defaultdict(set) - weight = {} - for index, equa in enumerate(equations): - graph[equa[0]].add(equa[1]) - graph[equa[1]].add(equa[0]) - weight[tuple(equa)] = values[index] - weight[(equa[1], equa[0])] = float(1 / values[index]) - - res = [] - for start, end in queries: - if (start, end) in weight: - res.append(weight[(start, end)]) - continue - if start not in graph or end not in graph: - res.append(-1) - continue - if start == end: - res.append(1.0) - continue - stack = collections.deque() - for temp in graph[start]: - stack.appendleft((temp, weight[(start, temp)])) - visited = {start} - flag = False - while stack: - c, w = stack.pop() - if c == end: - flag = True - res.append(w) - break - visited.add(c) - for n in graph[c]: - if n not in visited: - weight[(start, n)] = w * weight[(c, n)] - stack.appendleft((n, w * weight[(c, n)])) - if flag: - continue - res.append(-1.0) +# 首先要把除法运算转化成图表示,比如a->b = 2.0 b->c = 3.0, a,b,c看成节点,相除所得值为权值. +# 那么a/c = ? 就是相当于 a->c <==> a->b->c = 2.0*3.0 = 6,所以要把已知条件建图! + +# 深度优先搜索 +class Solution(object): + def calcEquation(self, equations, values, queries): + # 存放结点及其邻接点 + graph = collections.defaultdict(set) + # 存放每条边的权重 + weight = {} + # 构建图 + for index, equa in enumerate(equations): + graph[equa[0]].add(equa[1]) + graph[equa[1]].add(equa[0]) + weight[tuple(equa)] = values[index] + weight[(equa[1], equa[0])] = float(1 / values[index]) + + def dfs(start, end, visited): + # 图中有这条边,直接返回 + if (start, end) in weight: + return weight[(start, end)] + # 图中没有该结点 + if start not in graph or end not in graph: + return 0 + # 已经访问过 + if start in visited: + return 0 + # 当前结点正在访问 + visited.add(start) + w = 0 + # 深度优先遍历每个邻接点 + for temp in graph[start]: + w = (weight[(start, temp)] * dfs(temp, end, visited)) + # 遍历到一个可行解则退出 + if w != 0: + # 添加此边,以后访问节省时间 + weight[(start, end)] = w + break + # 访问完成 + visited.remove(start) + return w + + res = [] + for q in queries: + w = dfs(q[0], q[1], set()) + if w == 0: + w = -1.0 + res.append(w) + return res + + +# 广度优先搜索 +class Solution2(object): + def calcEquation(self, equations, values, queries): + graph = collections.defaultdict(set) + weight = {} + for index, equa in enumerate(equations): + graph[equa[0]].add(equa[1]) + graph[equa[1]].add(equa[0]) + weight[tuple(equa)] = values[index] + weight[(equa[1], equa[0])] = float(1 / values[index]) + + res = [] + for start, end in queries: + if (start, end) in weight: + res.append(weight[(start, end)]) + continue + if start not in graph or end not in graph: + res.append(-1) + continue + if start == end: + res.append(1.0) + continue + stack = collections.deque() + for temp in graph[start]: + stack.appendleft((temp, weight[(start, temp)])) + visited = {start} + flag = False + while stack: + c, w = stack.pop() + if c == end: + flag = True + res.append(w) + break + visited.add(c) + for n in graph[c]: + if n not in visited: + weight[(start, n)] = w * weight[(c, n)] + stack.appendleft((n, w * weight[(c, n)])) + if flag: + continue + res.append(-1.0) return res \ No newline at end of file diff --git "a/leetcode/400.\347\254\254N\344\270\252\346\225\260\345\255\227.py" "b/leetcode_Python/400.\347\254\254N\344\270\252\346\225\260\345\255\227.py" similarity index 97% rename from "leetcode/400.\347\254\254N\344\270\252\346\225\260\345\255\227.py" rename to "leetcode_Python/400.\347\254\254N\344\270\252\346\225\260\345\255\227.py" index 089115a..e4938e7 100644 --- "a/leetcode/400.\347\254\254N\344\270\252\346\225\260\345\255\227.py" +++ "b/leetcode_Python/400.\347\254\254N\344\270\252\346\225\260\345\255\227.py" @@ -1,15 +1,15 @@ -class Solution(object): - def findNthDigit(self, n): - # 数字位数 - digit = 1 - while 1: - # 不同位数的第一个整数 - first = 10**(digit-1) - # 该位数里的数字个数 - cur = 9 * first * digit - if cur >= n: - # str(first+(n-1)/digit) 获取第n个数所在的整数,(n-1)%digit获取该整数的哪个数 - return int(str(first + (n-1)/digit)[(n-1) % digit]) - # 减去不符合的前cur个数,从更长位数开始判断 - n -= cur +class Solution(object): + def findNthDigit(self, n): + # 数字位数 + digit = 1 + while 1: + # 不同位数的第一个整数 + first = 10**(digit-1) + # 该位数里的数字个数 + cur = 9 * first * digit + if cur >= n: + # str(first+(n-1)/digit) 获取第n个数所在的整数,(n-1)%digit获取该整数的哪个数 + return int(str(first + (n-1)/digit)[(n-1) % digit]) + # 减去不符合的前cur个数,从更长位数开始判断 + n -= cur digit += 1 \ No newline at end of file diff --git "a/leetcode/401.\344\272\214\350\277\233\345\210\266\346\211\213\350\241\250.py" "b/leetcode_Python/401.\344\272\214\350\277\233\345\210\266\346\211\213\350\241\250.py" similarity index 97% rename from "leetcode/401.\344\272\214\350\277\233\345\210\266\346\211\213\350\241\250.py" rename to "leetcode_Python/401.\344\272\214\350\277\233\345\210\266\346\211\213\350\241\250.py" index 1efba04..e231893 100644 --- "a/leetcode/401.\344\272\214\350\277\233\345\210\266\346\211\213\350\241\250.py" +++ "b/leetcode_Python/401.\344\272\214\350\277\233\345\210\266\346\211\213\350\241\250.py" @@ -1,10 +1,10 @@ -# 暴力破解 -class Solution(object): - def readBinaryWatch(self, num): - res = [] - for i in range(12): - for j in range(60): - if bin(i).count('1') + bin(j).count('1') == num: - s = str(i) + ':' + ('0'+str(j) if j<10 else str(j)) - res.append(s) +# 暴力破解 +class Solution(object): + def readBinaryWatch(self, num): + res = [] + for i in range(12): + for j in range(60): + if bin(i).count('1') + bin(j).count('1') == num: + s = str(i) + ':' + ('0'+str(j) if j<10 else str(j)) + res.append(s) return res \ No newline at end of file diff --git "a/leetcode/402.\347\247\273\346\216\211K\344\275\215\346\225\260\345\255\227.py" "b/leetcode_Python/402.\347\247\273\346\216\211K\344\275\215\346\225\260\345\255\227.py" similarity index 96% rename from "leetcode/402.\347\247\273\346\216\211K\344\275\215\346\225\260\345\255\227.py" rename to "leetcode_Python/402.\347\247\273\346\216\211K\344\275\215\346\225\260\345\255\227.py" index f2812a0..2e8543e 100644 --- "a/leetcode/402.\347\247\273\346\216\211K\344\275\215\346\225\260\345\255\227.py" +++ "b/leetcode_Python/402.\347\247\273\346\216\211K\344\275\215\346\225\260\345\255\227.py" @@ -1,17 +1,17 @@ -# 利用栈弹出元素,使前面的数字尽可能小 -class Solution(object): - def removeKdigits(self, num, k): - res = [] - for n in num: - while res: - if not k or n >= res[-1]: - res.append(n) - break - else: - res.pop() - k -= 1 - else: - if n != '0': - res.append(n) - res = res[:len(res)-k] +# 利用栈弹出元素,使前面的数字尽可能小 +class Solution(object): + def removeKdigits(self, num, k): + res = [] + for n in num: + while res: + if not k or n >= res[-1]: + res.append(n) + break + else: + res.pop() + k -= 1 + else: + if n != '0': + res.append(n) + res = res[:len(res)-k] return ''.join(res) if res else '0' \ No newline at end of file diff --git "a/leetcode/404.\345\267\246\345\217\266\345\255\220\344\271\213\345\222\214.py" "b/leetcode_Python/404.\345\267\246\345\217\266\345\255\220\344\271\213\345\222\214.py" similarity index 97% rename from "leetcode/404.\345\267\246\345\217\266\345\255\220\344\271\213\345\222\214.py" rename to "leetcode_Python/404.\345\267\246\345\217\266\345\255\220\344\271\213\345\222\214.py" index 555ae1e..987e96a 100644 --- "a/leetcode/404.\345\267\246\345\217\266\345\255\220\344\271\213\345\222\214.py" +++ "b/leetcode_Python/404.\345\267\246\345\217\266\345\255\220\344\271\213\345\222\214.py" @@ -1,19 +1,19 @@ -# 对于左孩子,判断是否为叶子结点,是则加上该值,不是则递归。对于右孩子,直接递归 -class Solution(object): - def sumOfLeftLeaves(self, root): - # 判断是否为叶子 - def isLeaf(node): - if not node: - return False - if not node.left and not node.right: - return True - return False - - res = 0 - if root: - if isLeaf(root.left): - res += root.left.val - else: - res += self.sumOfLeftLeaves(root.left) - res += self.sumOfLeftLeaves(root.right) +# 对于左孩子,判断是否为叶子结点,是则加上该值,不是则递归。对于右孩子,直接递归 +class Solution(object): + def sumOfLeftLeaves(self, root): + # 判断是否为叶子 + def isLeaf(node): + if not node: + return False + if not node.left and not node.right: + return True + return False + + res = 0 + if root: + if isLeaf(root.left): + res += root.left.val + else: + res += self.sumOfLeftLeaves(root.left) + res += self.sumOfLeftLeaves(root.right) return res \ No newline at end of file diff --git "a/leetcode/406.\346\240\271\346\215\256\350\272\253\351\253\230\351\207\215\345\273\272\351\230\237\345\210\227.py" "b/leetcode_Python/406.\346\240\271\346\215\256\350\272\253\351\253\230\351\207\215\345\273\272\351\230\237\345\210\227.py" similarity index 97% rename from "leetcode/406.\346\240\271\346\215\256\350\272\253\351\253\230\351\207\215\345\273\272\351\230\237\345\210\227.py" rename to "leetcode_Python/406.\346\240\271\346\215\256\350\272\253\351\253\230\351\207\215\345\273\272\351\230\237\345\210\227.py" index 4c6e47a..ab5070d 100644 --- "a/leetcode/406.\346\240\271\346\215\256\350\272\253\351\253\230\351\207\215\345\273\272\351\230\237\345\210\227.py" +++ "b/leetcode_Python/406.\346\240\271\346\215\256\350\272\253\351\253\230\351\207\215\345\273\272\351\230\237\345\210\227.py" @@ -1,8 +1,8 @@ -# 先按身高降序排序,身高相同则按k升序排序。再以k为索引插入排序 -class Solution(object): - def reconstructQueue(self, people): - people.sort(key=lambda x:(-x[0], x[1])) - res = [] - for p in people: - res.insert(p[1], p) - return res +# 先按身高降序排序,身高相同则按k升序排序。再以k为索引插入排序 +class Solution(object): + def reconstructQueue(self, people): + people.sort(key=lambda x:(-x[0], x[1])) + res = [] + for p in people: + res.insert(p[1], p) + return res diff --git "a/leetcode/409.\346\234\200\351\225\277\345\233\236\346\226\207\344\270\262.py" "b/leetcode_Python/409.\346\234\200\351\225\277\345\233\236\346\226\207\344\270\262.py" similarity index 97% rename from "leetcode/409.\346\234\200\351\225\277\345\233\236\346\226\207\344\270\262.py" rename to "leetcode_Python/409.\346\234\200\351\225\277\345\233\236\346\226\207\344\270\262.py" index 99637ad..1eff6f6 100644 --- "a/leetcode/409.\346\234\200\351\225\277\345\233\236\346\226\207\344\270\262.py" +++ "b/leetcode_Python/409.\346\234\200\351\225\277\345\233\236\346\226\207\344\270\262.py" @@ -1,13 +1,13 @@ -# 统计字符个数存放在字典中,遍历字典。字符个数为偶数则直接累加。 -# 个数为奇数则减1后累加,由于回文串只能有一个字符是奇次数,故若有字符个数是奇数最后要再加1 -class Solution(object): - def longestPalindrome(self, s): - d = collections.Counter(s) - length = k = 0 - for key in d: - if d[key]%2 == 0: - length += d[key] - else: - k = 1 - length += d[key]-1 +# 统计字符个数存放在字典中,遍历字典。字符个数为偶数则直接累加。 +# 个数为奇数则减1后累加,由于回文串只能有一个字符是奇次数,故若有字符个数是奇数最后要再加1 +class Solution(object): + def longestPalindrome(self, s): + d = collections.Counter(s) + length = k = 0 + for key in d: + if d[key]%2 == 0: + length += d[key] + else: + k = 1 + length += d[key]-1 return length + k \ No newline at end of file diff --git a/leetcode/412.Fizz Buzz.py b/leetcode_Python/412.Fizz Buzz.py similarity index 96% rename from leetcode/412.Fizz Buzz.py rename to leetcode_Python/412.Fizz Buzz.py index 2ac5f27..8a73977 100644 --- a/leetcode/412.Fizz Buzz.py +++ b/leetcode_Python/412.Fizz Buzz.py @@ -1,13 +1,13 @@ -class Solution(object): - def fizzBuzz(self, n): - res = [] - for i in range(1, n+1): - if i%3==0 and i%5==0: - res.append('FizzBuzz') - elif i%3==0: - res.append('Fizz') - elif i%5==0: - res.append('Buzz') - else: - res.append(str(i)) +class Solution(object): + def fizzBuzz(self, n): + res = [] + for i in range(1, n+1): + if i%3==0 and i%5==0: + res.append('FizzBuzz') + elif i%3==0: + res.append('Fizz') + elif i%5==0: + res.append('Buzz') + else: + res.append(str(i)) return res \ No newline at end of file diff --git "a/leetcode/413.\347\255\211\345\267\256\346\225\260\345\210\227\345\210\222\345\210\206.py" "b/leetcode_Python/413.\347\255\211\345\267\256\346\225\260\345\210\227\345\210\222\345\210\206.py" similarity index 98% rename from "leetcode/413.\347\255\211\345\267\256\346\225\260\345\210\227\345\210\222\345\210\206.py" rename to "leetcode_Python/413.\347\255\211\345\267\256\346\225\260\345\210\227\345\210\222\345\210\206.py" index bcc317f..f1e88ec 100644 --- "a/leetcode/413.\347\255\211\345\267\256\346\225\260\345\210\227\345\210\222\345\210\206.py" +++ "b/leetcode_Python/413.\347\255\211\345\267\256\346\225\260\345\210\227\345\210\222\345\210\206.py" @@ -1,8 +1,8 @@ -# 动态规划,dp[i]记录增加元素A[i]与前面构成等差数列时,新增的等差数列子数组个数,且个数刚好为前一状态新增个数加1 -class Solution(object): - def numberOfArithmeticSlices(self, A): - dp = [0]*len(A) - for i in range(2, len(A)): - if A[i] - A[i-1] == A[i-1] - A[i-2]: - dp[i] = dp[i-1] + 1 - return sum(dp) +# 动态规划,dp[i]记录增加元素A[i]与前面构成等差数列时,新增的等差数列子数组个数,且个数刚好为前一状态新增个数加1 +class Solution(object): + def numberOfArithmeticSlices(self, A): + dp = [0]*len(A) + for i in range(2, len(A)): + if A[i] - A[i-1] == A[i-1] - A[i-2]: + dp[i] = dp[i-1] + 1 + return sum(dp) diff --git "a/leetcode/414.\347\254\254\344\270\211\345\244\247\347\232\204\346\225\260.py" "b/leetcode_Python/414.\347\254\254\344\270\211\345\244\247\347\232\204\346\225\260.py" similarity index 96% rename from "leetcode/414.\347\254\254\344\270\211\345\244\247\347\232\204\346\225\260.py" rename to "leetcode_Python/414.\347\254\254\344\270\211\345\244\247\347\232\204\346\225\260.py" index 7efe80a..dace0de 100644 --- "a/leetcode/414.\347\254\254\344\270\211\345\244\247\347\232\204\346\225\260.py" +++ "b/leetcode_Python/414.\347\254\254\344\270\211\345\244\247\347\232\204\346\225\260.py" @@ -1,7 +1,7 @@ -# 去重排序 -class Solution(object): - def thirdMax(self, nums): - n = sorted(list(set(nums))) - if len(n) < 3: - return n[-1] +# 去重排序 +class Solution(object): + def thirdMax(self, nums): + n = sorted(list(set(nums))) + if len(n) < 3: + return n[-1] return n[-3] \ No newline at end of file diff --git "a/leetcode/415.\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240.py" "b/leetcode_Python/415.\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240.py" similarity index 97% rename from "leetcode/415.\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240.py" rename to "leetcode_Python/415.\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240.py" index cfd75b6..cba6de1 100644 --- "a/leetcode/415.\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240.py" +++ "b/leetcode_Python/415.\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240.py" @@ -1,4 +1,4 @@ -# eval()执行字符串表达式 -class Solution(object): - def addStrings(self, num1, num2): +# eval()执行字符串表达式 +class Solution(object): + def addStrings(self, num1, num2): return str(eval(num1) + eval(num2)) \ No newline at end of file diff --git "a/leetcode/419.\347\224\262\346\235\277\344\270\212\347\232\204\346\210\230\350\210\260.py" "b/leetcode_Python/419.\347\224\262\346\235\277\344\270\212\347\232\204\346\210\230\350\210\260.py" similarity index 97% rename from "leetcode/419.\347\224\262\346\235\277\344\270\212\347\232\204\346\210\230\350\210\260.py" rename to "leetcode_Python/419.\347\224\262\346\235\277\344\270\212\347\232\204\346\210\230\350\210\260.py" index 60460aa..d4c2516 100644 --- "a/leetcode/419.\347\224\262\346\235\277\344\270\212\347\232\204\346\210\230\350\210\260.py" +++ "b/leetcode_Python/419.\347\224\262\346\235\277\344\270\212\347\232\204\346\210\230\350\210\260.py" @@ -1,11 +1,11 @@ -# 遍历时如果为'X',并且其左边和上边不为'X',则个数加1 -class Solution(object): - def countBattleships(self, board): - res = 0 - for i in range(len(board)): - for j in range(len(board[0])): - if board[i][j] == 'X': - if (i > 0 and board[i-1][j] == 'X') or (j > 0 and board[i][j-1] == 'X'): - continue - res += 1 +# 遍历时如果为'X',并且其左边和上边不为'X',则个数加1 +class Solution(object): + def countBattleships(self, board): + res = 0 + for i in range(len(board)): + for j in range(len(board[0])): + if board[i][j] == 'X': + if (i > 0 and board[i-1][j] == 'X') or (j > 0 and board[i][j-1] == 'X'): + continue + res += 1 return res \ No newline at end of file diff --git "a/leetcode/429.N\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" "b/leetcode_Python/429.N\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" similarity index 97% rename from "leetcode/429.N\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" rename to "leetcode_Python/429.N\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" index 9ec7d65..a4644ab 100644 --- "a/leetcode/429.N\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" +++ "b/leetcode_Python/429.N\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206.py" @@ -1,17 +1,17 @@ -# cur_level:存放当前行结点 -# next_level:存放下一行结点 -# cur_val:存放当前行的值 -# res:存放所有行的值 -class Solution(object): - def levelOrder(self, root): - if not root: - return [] - res, cur_level, next_level, cur_val = [], [root], [], [] - while cur_level: - for node in cur_level: - cur_val.append(node.val) - for child in node.children: - next_level.append(child) - res.append(cur_val) - cur_level, next_level, cur_val = next_level, [], [] +# cur_level:存放当前行结点 +# next_level:存放下一行结点 +# cur_val:存放当前行的值 +# res:存放所有行的值 +class Solution(object): + def levelOrder(self, root): + if not root: + return [] + res, cur_level, next_level, cur_val = [], [root], [], [] + while cur_level: + for node in cur_level: + cur_val.append(node.val) + for child in node.children: + next_level.append(child) + res.append(cur_val) + cur_level, next_level, cur_val = next_level, [], [] return res \ No newline at end of file diff --git "a/leetcode/430.\346\211\201\345\271\263\345\214\226\345\244\232\347\272\247\345\217\214\345\220\221\351\223\276\350\241\250.py" "b/leetcode_Python/430.\346\211\201\345\271\263\345\214\226\345\244\232\347\272\247\345\217\214\345\220\221\351\223\276\350\241\250.py" similarity index 97% rename from "leetcode/430.\346\211\201\345\271\263\345\214\226\345\244\232\347\272\247\345\217\214\345\220\221\351\223\276\350\241\250.py" rename to "leetcode_Python/430.\346\211\201\345\271\263\345\214\226\345\244\232\347\272\247\345\217\214\345\220\221\351\223\276\350\241\250.py" index 288cb23..3e7e89d 100644 --- "a/leetcode/430.\346\211\201\345\271\263\345\214\226\345\244\232\347\272\247\345\217\214\345\220\221\351\223\276\350\241\250.py" +++ "b/leetcode_Python/430.\346\211\201\345\271\263\345\214\226\345\244\232\347\272\247\345\217\214\345\220\221\351\223\276\350\241\250.py" @@ -1,19 +1,19 @@ -# 如果head有child,则child为头结点的链表尾结点与head.next互连,然后head跟child互连。 -class Solution(object): - def flatten(self, head): - if not head: - return head - s = Node(None, None, head, None) - while head: - if head.child: - child = head.child - child.prev = head - while child.next: - child = child.next - child.next = head.next - if head.next: - head.next.prev = child - head.next = head.child - head.child = None - head = head.next +# 如果head有child,则child为头结点的链表尾结点与head.next互连,然后head跟child互连。 +class Solution(object): + def flatten(self, head): + if not head: + return head + s = Node(None, None, head, None) + while head: + if head.child: + child = head.child + child.prev = head + while child.next: + child = child.next + child.next = head.next + if head.next: + head.next.prev = child + head.next = head.child + head.child = None + head = head.next return s.next \ No newline at end of file diff --git "a/leetcode/434.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215\346\225\260.py" "b/leetcode_Python/434.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215\346\225\260.py" similarity index 98% rename from "leetcode/434.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215\346\225\260.py" rename to "leetcode_Python/434.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215\346\225\260.py" index a09562f..3928f5a 100644 --- "a/leetcode/434.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215\346\225\260.py" +++ "b/leetcode_Python/434.\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215\346\225\260.py" @@ -1,3 +1,3 @@ -class Solution(object): - def countSegments(self, s): +class Solution(object): + def countSegments(self, s): return len([word for word in s.split()]) \ No newline at end of file diff --git "a/leetcode/435.\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" "b/leetcode_Python/435.\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" similarity index 98% rename from "leetcode/435.\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" rename to "leetcode_Python/435.\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" index c5419ae..b2662f8 100644 --- "a/leetcode/435.\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" +++ "b/leetcode_Python/435.\346\227\240\351\207\215\345\217\240\345\214\272\351\227\264.py" @@ -1,13 +1,13 @@ -# 贪心算法。按结尾升序排序,以最小结尾与其他区间的开头比较,跳过重叠的区间,记录不重叠区间的个数,并更新结尾,再相减得到要移除的区间个数。 -class Solution(object): - def eraseOverlapIntervals(self, intervals): - if not intervals: - return 0 - intervals = sorted(intervals, key=lambda k: k[1]) - end, count, n = intervals[0][1], 1, len(intervals) - for i in range(1, n): - if intervals[i][0] < end: - continue - count += 1 - end = intervals[i][1] +# 贪心算法。按结尾升序排序,以最小结尾与其他区间的开头比较,跳过重叠的区间,记录不重叠区间的个数,并更新结尾,再相减得到要移除的区间个数。 +class Solution(object): + def eraseOverlapIntervals(self, intervals): + if not intervals: + return 0 + intervals = sorted(intervals, key=lambda k: k[1]) + end, count, n = intervals[0][1], 1, len(intervals) + for i in range(1, n): + if intervals[i][0] < end: + continue + count += 1 + end = intervals[i][1] return n-count \ No newline at end of file diff --git "a/leetcode/437.\350\267\257\345\276\204\346\200\273\345\222\214III.py" "b/leetcode_Python/437.\350\267\257\345\276\204\346\200\273\345\222\214III.py" similarity index 97% rename from "leetcode/437.\350\267\257\345\276\204\346\200\273\345\222\214III.py" rename to "leetcode_Python/437.\350\267\257\345\276\204\346\200\273\345\222\214III.py" index b3bd7ac..c51a334 100644 --- "a/leetcode/437.\350\267\257\345\276\204\346\200\273\345\222\214III.py" +++ "b/leetcode_Python/437.\350\267\257\345\276\204\346\200\273\345\222\214III.py" @@ -1,16 +1,16 @@ -class Solution(object): - def pathSum(self, root, sum): - if not root: - return 0 - return self.dfs(root, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum) - - # 计算某结点开始符合的路径数 - def dfs(self, root, sum): - res = 0 - if not root: - return res - if root.val==sum: - res += 1 - res += self.dfs(root.left, sum-root.val) - res += self.dfs(root.right, sum-root.val) +class Solution(object): + def pathSum(self, root, sum): + if not root: + return 0 + return self.dfs(root, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum) + + # 计算某结点开始符合的路径数 + def dfs(self, root, sum): + res = 0 + if not root: + return res + if root.val==sum: + res += 1 + res += self.dfs(root.left, sum-root.val) + res += self.dfs(root.right, sum-root.val) return res \ No newline at end of file diff --git "a/leetcode/441.\346\216\222\345\210\227\347\241\254\345\270\201.py" "b/leetcode_Python/441.\346\216\222\345\210\227\347\241\254\345\270\201.py" similarity index 97% rename from "leetcode/441.\346\216\222\345\210\227\347\241\254\345\270\201.py" rename to "leetcode_Python/441.\346\216\222\345\210\227\347\241\254\345\270\201.py" index e790ed2..923ad44 100644 --- "a/leetcode/441.\346\216\222\345\210\227\347\241\254\345\270\201.py" +++ "b/leetcode_Python/441.\346\216\222\345\210\227\347\241\254\345\270\201.py" @@ -1,8 +1,8 @@ -# 每增加一行,当前总硬币数增加该行的行号,当前总硬币数小于等于n时循环,大于时则上一行的行号即为所求总行数 -class Solution(object): - def arrangeCoins(self, n): - i = nums = 0 - while nums <= n: - i += 1 - nums += i +# 每增加一行,当前总硬币数增加该行的行号,当前总硬币数小于等于n时循环,大于时则上一行的行号即为所求总行数 +class Solution(object): + def arrangeCoins(self, n): + i = nums = 0 + while nums <= n: + i += 1 + nums += i return i-1 \ No newline at end of file diff --git "a/leetcode/443.\345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/443.\345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "leetcode/443.\345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/443.\345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.py" index eccf71f..10dc219 100644 --- "a/leetcode/443.\345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/443.\345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.py" @@ -1,24 +1,24 @@ -class Solution(object): - def compress(self, chars): - n = len(chars) - cur = 0 - i = 0 - while i < n: - # 将j索引指向最后一个重复的字符 - j = i - while j < n-1 and chars[j] == chars[j+1]: - j += 1 - # 保存当前字符,cur移到下一位索引 - chars[cur] = chars[i] - cur += 1 - # 有重复字符 - if i != j: - times = str(j-i+1) - tLen = len(times) - for k in range(tLen): - chars[cur+k] = times[k] - cur += tLen - # 继续判断下个字符 - i = j+1 - # 返回索引代表数组长度 +class Solution(object): + def compress(self, chars): + n = len(chars) + cur = 0 + i = 0 + while i < n: + # 将j索引指向最后一个重复的字符 + j = i + while j < n-1 and chars[j] == chars[j+1]: + j += 1 + # 保存当前字符,cur移到下一位索引 + chars[cur] = chars[i] + cur += 1 + # 有重复字符 + if i != j: + times = str(j-i+1) + tLen = len(times) + for k in range(tLen): + chars[cur+k] = times[k] + cur += tLen + # 继续判断下个字符 + i = j+1 + # 返回索引代表数组长度 return cur \ No newline at end of file diff --git "a/leetcode/445.\344\270\244\346\225\260\347\233\270\345\212\240II.py" "b/leetcode_Python/445.\344\270\244\346\225\260\347\233\270\345\212\240II.py" similarity index 96% rename from "leetcode/445.\344\270\244\346\225\260\347\233\270\345\212\240II.py" rename to "leetcode_Python/445.\344\270\244\346\225\260\347\233\270\345\212\240II.py" index 21e060d..5d9d99a 100644 --- "a/leetcode/445.\344\270\244\346\225\260\347\233\270\345\212\240II.py" +++ "b/leetcode_Python/445.\344\270\244\346\225\260\347\233\270\345\212\240II.py" @@ -1,16 +1,16 @@ -# 将链表转化为整型,相加后将结果转化为链表 -class Solution(object): - def addTwoNumbers(self, l1, l2): - s1 = s2 = '' - while l1: - s1 += str(l1.val) - l1 = l1.next - while l2: - s2 += str(l2.val) - l2 = l2.next - s3 = str(int(s1) + int(s2)) - res = head = ListNode(int(s3[0])) - for i in s3[1:]: - head.next = ListNode(int(i)) - head = head.next +# 将链表转化为整型,相加后将结果转化为链表 +class Solution(object): + def addTwoNumbers(self, l1, l2): + s1 = s2 = '' + while l1: + s1 += str(l1.val) + l1 = l1.next + while l2: + s2 += str(l2.val) + l2 = l2.next + s3 = str(int(s1) + int(s2)) + res = head = ListNode(int(s3[0])) + for i in s3[1:]: + head.next = ListNode(int(i)) + head = head.next return res \ No newline at end of file diff --git "a/leetcode/448.\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" "b/leetcode_Python/448.\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" similarity index 98% rename from "leetcode/448.\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" rename to "leetcode_Python/448.\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" index a7b093b..7692bee 100644 --- "a/leetcode/448.\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" +++ "b/leetcode_Python/448.\346\211\276\345\210\260\346\211\200\346\234\211\346\225\260\347\273\204\344\270\255\346\266\210\345\244\261\347\232\204\346\225\260\345\255\227.py" @@ -1,3 +1,3 @@ -class Solution(object): - def findDisappearedNumbers(self, nums): +class Solution(object): + def findDisappearedNumbers(self, nums): return list(set(range(1, len(nums)+1)) - set(nums)) \ No newline at end of file diff --git "a/leetcode/449.\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/449.\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 96% rename from "leetcode/449.\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/449.\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index 563a681..52ac9d2 100644 --- "a/leetcode/449.\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/449.\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,27 +1,27 @@ -class Codec: - - def serialize(self, root): - def preorder(root): - if root: - res.append(str(root.val)) - preorder(root.left) - preorder(root.right) - else: - res.append('#') - - res = [] - preorder(root) - return ','.join(res) - - def deserialize(self, data): - def createtree(): - val = next(vals) - if val == '#': - return - root = TreeNode(int(val)) - root.left = createtree() - root.right = createtree() - return root - - vals = iter(data.split(',')) +class Codec: + + def serialize(self, root): + def preorder(root): + if root: + res.append(str(root.val)) + preorder(root.left) + preorder(root.right) + else: + res.append('#') + + res = [] + preorder(root) + return ','.join(res) + + def deserialize(self, data): + def createtree(): + val = next(vals) + if val == '#': + return + root = TreeNode(int(val)) + root.left = createtree() + root.right = createtree() + return root + + vals = iter(data.split(',')) return createtree() \ No newline at end of file diff --git "a/leetcode/450.\345\210\240\351\231\244\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\347\273\223\347\202\271.py" "b/leetcode_Python/450.\345\210\240\351\231\244\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\347\273\223\347\202\271.py" similarity index 97% rename from "leetcode/450.\345\210\240\351\231\244\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\347\273\223\347\202\271.py" rename to "leetcode_Python/450.\345\210\240\351\231\244\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\347\273\223\347\202\271.py" index dc5d71e..027c246 100644 --- "a/leetcode/450.\345\210\240\351\231\244\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\347\273\223\347\202\271.py" +++ "b/leetcode_Python/450.\345\210\240\351\231\244\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\347\273\223\347\202\271.py" @@ -1,46 +1,46 @@ -# 如果key结点没有孩子或只有一个孩子,则将key结点指针指向空或指向孩子,即删除了key结点 -# 如果key结点有两个孩子,则用其右子树中的最小值替换掉key结点,然后将右子树中的这一最小值递归地删除 -class Solution(object): - def deleteNode(self, root, key): - # 找树的最小值 - def findmin(root): - while root.left: - root = root.left - return root.val - - if not root: - return - elif key < root.val: - # 递归,在左子树中删除key结点,然后返回左子树新的根给根的左孩子 - root.left = self.deleteNode(root.left, key) - elif key > root.val: - # 递归,在右子树中删除key结点,然后返回右子树新的根给根的右孩子 - root.right = self.deleteNode(root.right, key) - # 找到key结点 - else: - # 有左右孩子,用其右子树中的最小值替换掉key结点 - if root.left and root.right: - minNum = findmin(root.right) - root.val = minNum - # 在右子树中删除最小值结点,然后返回右子树新的根给右孩子 - root.right = self.deleteNode(root.right, minNum) - elif root.left: - root = root.left - else: - # 可能有右孩子,也可能为空 - root = root.right - return root - -################################### 递归思路 ############################# -# 方法作用极简化:先去掉递归的部分,再判断 无/1/2/3个结点的情况 -# 所以deleteNode方法的作用是,以key结点为根的树,将根指针指向左孩子或右孩子或空,即删除了key结点,然后返回新的根 -class Solution(object): - def deleteNode(self, root, key): - if not root: - return - else: - if root.left: - root = root.left - else: - root = root.right +# 如果key结点没有孩子或只有一个孩子,则将key结点指针指向空或指向孩子,即删除了key结点 +# 如果key结点有两个孩子,则用其右子树中的最小值替换掉key结点,然后将右子树中的这一最小值递归地删除 +class Solution(object): + def deleteNode(self, root, key): + # 找树的最小值 + def findmin(root): + while root.left: + root = root.left + return root.val + + if not root: + return + elif key < root.val: + # 递归,在左子树中删除key结点,然后返回左子树新的根给根的左孩子 + root.left = self.deleteNode(root.left, key) + elif key > root.val: + # 递归,在右子树中删除key结点,然后返回右子树新的根给根的右孩子 + root.right = self.deleteNode(root.right, key) + # 找到key结点 + else: + # 有左右孩子,用其右子树中的最小值替换掉key结点 + if root.left and root.right: + minNum = findmin(root.right) + root.val = minNum + # 在右子树中删除最小值结点,然后返回右子树新的根给右孩子 + root.right = self.deleteNode(root.right, minNum) + elif root.left: + root = root.left + else: + # 可能有右孩子,也可能为空 + root = root.right + return root + +################################### 递归思路 ############################# +# 方法作用极简化:先去掉递归的部分,再判断 无/1/2/3个结点的情况 +# 所以deleteNode方法的作用是,以key结点为根的树,将根指针指向左孩子或右孩子或空,即删除了key结点,然后返回新的根 +class Solution(object): + def deleteNode(self, root, key): + if not root: + return + else: + if root.left: + root = root.left + else: + root = root.right return root \ No newline at end of file diff --git "a/leetcode/453.\346\234\200\345\260\217\347\247\273\345\212\250\346\254\241\346\225\260\344\275\277\346\225\260\347\273\204\345\205\203\347\264\240\347\233\270\347\255\211.py" "b/leetcode_Python/453.\346\234\200\345\260\217\347\247\273\345\212\250\346\254\241\346\225\260\344\275\277\346\225\260\347\273\204\345\205\203\347\264\240\347\233\270\347\255\211.py" similarity index 97% rename from "leetcode/453.\346\234\200\345\260\217\347\247\273\345\212\250\346\254\241\346\225\260\344\275\277\346\225\260\347\273\204\345\205\203\347\264\240\347\233\270\347\255\211.py" rename to "leetcode_Python/453.\346\234\200\345\260\217\347\247\273\345\212\250\346\254\241\346\225\260\344\275\277\346\225\260\347\273\204\345\205\203\347\264\240\347\233\270\347\255\211.py" index 3ad8bd8..41538ca 100644 --- "a/leetcode/453.\346\234\200\345\260\217\347\247\273\345\212\250\346\254\241\346\225\260\344\275\277\346\225\260\347\273\204\345\205\203\347\264\240\347\233\270\347\255\211.py" +++ "b/leetcode_Python/453.\346\234\200\345\260\217\347\247\273\345\212\250\346\254\241\346\225\260\344\275\277\346\225\260\347\273\204\345\205\203\347\264\240\347\233\270\347\255\211.py" @@ -1,13 +1,13 @@ -# 方法一:每次移动可以使n-1个元素增加1,即使最大元素减1,循环达到所有元素值都为最小元素值 -class Solution(object): - def minMoves(self, nums): - min_v = min(nums) - count = 0 - for num in nums: - count += num-min_v - return count - -# 方法二:即方法一同样思路另一种写法 -class Solution(object): - def minMoves(self, nums): +# 方法一:每次移动可以使n-1个元素增加1,即使最大元素减1,循环达到所有元素值都为最小元素值 +class Solution(object): + def minMoves(self, nums): + min_v = min(nums) + count = 0 + for num in nums: + count += num-min_v + return count + +# 方法二:即方法一同样思路另一种写法 +class Solution(object): + def minMoves(self, nums): return sum(nums) - min(nums) * len(nums) \ No newline at end of file diff --git "a/leetcode/455.\345\210\206\345\217\221\351\245\274\345\271\262.py" "b/leetcode_Python/455.\345\210\206\345\217\221\351\245\274\345\271\262.py" similarity index 97% rename from "leetcode/455.\345\210\206\345\217\221\351\245\274\345\271\262.py" rename to "leetcode_Python/455.\345\210\206\345\217\221\351\245\274\345\271\262.py" index 2206cfa..f4aa6e5 100644 --- "a/leetcode/455.\345\210\206\345\217\221\351\245\274\345\271\262.py" +++ "b/leetcode_Python/455.\345\210\206\345\217\221\351\245\274\345\271\262.py" @@ -1,14 +1,14 @@ -# 用两个指针指向两个排序后数组的首部,比较两个指针指向的元素。若饼干尺寸满足胃口值则两指针各前进一步,否则饼干指针前进一步 -class Solution(object): - def findContentChildren(self, g, s): - g.sort() - s.sort() - len_g, len_s = len(g), len(s) - i = j = 0 - while i0 and grid[i-1][j]==1: - res -= 2 - # 右边为1时不用管,左边为1时再一起减2 - if j>0 and grid[i][j-1]==1: - res -= 2 - return res +class Solution(object): + def islandPerimeter(self, grid): + res = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 1: + res += 4 + # 下边为1时不用管,上边为1时再一起减2 + if i>0 and grid[i-1][j]==1: + res -= 2 + # 右边为1时不用管,左边为1时再一起减2 + if j>0 and grid[i][j-1]==1: + res -= 2 + return res diff --git "a/leetcode/470.\347\224\250 Rand7() \345\256\236\347\216\260 Rand10().py" "b/leetcode_Python/470.\347\224\250 Rand7() \345\256\236\347\216\260 Rand10().py" similarity index 95% rename from "leetcode/470.\347\224\250 Rand7() \345\256\236\347\216\260 Rand10().py" rename to "leetcode_Python/470.\347\224\250 Rand7() \345\256\236\347\216\260 Rand10().py" index 2782829..b057d55 100644 --- "a/leetcode/470.\347\224\250 Rand7() \345\256\236\347\216\260 Rand10().py" +++ "b/leetcode_Python/470.\347\224\250 Rand7() \345\256\236\347\216\260 Rand10().py" @@ -1,52 +1,52 @@ -# 拒绝采样 -# a 1 2 3 4 5 6 7 -# b -# 1 2 3 4 5 6 7 8 -# 2 3 4 5 6 7 8 9 -# 3 4 5 6 7 8 9 0 -# 4 5 6 7 8 9 0 1 -# 5 6 7 8 9 0 1 2 -# 6 7 8 9 0 1 2 3 -# 7 8 9 0 1 2 3 4 -# 去掉右上角 -# 6 7 8 -# 7 8 9 -# 8 9 0 -# 则每个数字的出现次数为4次,0-9的概率相同 -class Solution(object): - def rand10(self): - a, b = rand7(), rand7() - if a > 4 and b < 4: - return self.rand10() - return (a+b) % 10 + 1 - - -# b 1 2 3 4 5 6 7 -# a -# 1 1 2 3 4 5 6 7 -# 2 8 9 10 1 2 3 4 -# 3 5 6 7 8 9 10 1 -# 4 2 3 4 5 6 7 8 -# 5 9 10 1 2 3 4 5 -# 6 6 7 8 9 10 1 2 -# 7 3 4 5 6 7 8 9 -class Solution2(object): - def rand10(self): - a, b = rand7(), rand7() - if (a == 6 and b > 5) or a == 7: - return self.rand10() - return ((a-1)*7 + b-1) % 10 + 1 - - -# (rand7()-1)*7 等概率产生0 7 14 21 28 35 42 -# rand7()-1 等概率产生 0 1 2 3 4 5 6 -# 两者相加则等概率产生 0-42,在大的等概率空间中取小范围的数 -class Solution3(object): - def rand10(self): - while 1: - num = (rand7()-1)*7 + rand7()-1 - if num < 40: - return num % 10 + 1 - - - +# 拒绝采样 +# a 1 2 3 4 5 6 7 +# b +# 1 2 3 4 5 6 7 8 +# 2 3 4 5 6 7 8 9 +# 3 4 5 6 7 8 9 0 +# 4 5 6 7 8 9 0 1 +# 5 6 7 8 9 0 1 2 +# 6 7 8 9 0 1 2 3 +# 7 8 9 0 1 2 3 4 +# 去掉右上角 +# 6 7 8 +# 7 8 9 +# 8 9 0 +# 则每个数字的出现次数为4次,0-9的概率相同 +class Solution(object): + def rand10(self): + a, b = rand7(), rand7() + if a > 4 and b < 4: + return self.rand10() + return (a+b) % 10 + 1 + + +# b 1 2 3 4 5 6 7 +# a +# 1 1 2 3 4 5 6 7 +# 2 8 9 10 1 2 3 4 +# 3 5 6 7 8 9 10 1 +# 4 2 3 4 5 6 7 8 +# 5 9 10 1 2 3 4 5 +# 6 6 7 8 9 10 1 2 +# 7 3 4 5 6 7 8 9 +class Solution2(object): + def rand10(self): + a, b = rand7(), rand7() + if (a == 6 and b > 5) or a == 7: + return self.rand10() + return ((a-1)*7 + b-1) % 10 + 1 + + +# (rand7()-1)*7 等概率产生0 7 14 21 28 35 42 +# rand7()-1 等概率产生 0 1 2 3 4 5 6 +# 两者相加则等概率产生 0-42,在大的等概率空间中取小范围的数 +class Solution3(object): + def rand10(self): + while 1: + num = (rand7()-1)*7 + rand7()-1 + if num < 40: + return num % 10 + 1 + + + diff --git "a/leetcode/473.\347\201\253\346\237\264\346\213\274\346\255\243\346\226\271\345\275\242.py" "b/leetcode_Python/473.\347\201\253\346\237\264\346\213\274\346\255\243\346\226\271\345\275\242.py" similarity index 97% rename from "leetcode/473.\347\201\253\346\237\264\346\213\274\346\255\243\346\226\271\345\275\242.py" rename to "leetcode_Python/473.\347\201\253\346\237\264\346\213\274\346\255\243\346\226\271\345\275\242.py" index d333326..eec5b06 100644 --- "a/leetcode/473.\347\201\253\346\237\264\346\213\274\346\255\243\346\226\271\345\275\242.py" +++ "b/leetcode_Python/473.\347\201\253\346\237\264\346\213\274\346\255\243\346\226\271\345\275\242.py" @@ -1,39 +1,39 @@ -# 递归,贪心,深度优先,剪枝 -# 每次尝试把每根火柴拼到4条边,全部拼完则可以组成正方形 -class Solution(object): - def makesquare(self, nums): - # 不能组成正方形的情况:1.火柴总长度不是4的倍数 2.火柴数少于4 3.最长的火柴大于目标边长 - sums = sum(nums) - if sums % 4 or len(nums) < 4: - return False - # 贪心,先排序可以节约回溯的次数 - nums.sort(reverse=True) - side_len = sums / 4 - if nums[0] > side_len: - return False - - def dfs(i, sides): - """ - 深度优先遍历 - :param i: 当前访问的火柴的位置 - :param sides: 当前4条边的长度 - :return: - """ - # 递归终止条件,火柴全部拼完 - if i == len(nums): - return True - # 尝试把火柴拼到4条边中 - for j in range(4): - # 当前边长加上新的火柴后长度小于等于目标边长。当前边长与前一边长相等时可跳过,以为如果前一边长失败,当前边长也会失败 - if sides[j] + nums[i] <= side_len and (j == 0 or sides[j] != sides[j - 1]): - # 放入当前火柴 - sides[j] += nums[i] - # 放入下一根火柴 - if dfs(i + 1, sides): - return True - # 放入失败,取出火柴准备放入下一条边 - sides[j] -= nums[i] - # 四条边都不能放火柴,回溯 - return False - # 初始化边并从0开始放入 +# 递归,贪心,深度优先,剪枝 +# 每次尝试把每根火柴拼到4条边,全部拼完则可以组成正方形 +class Solution(object): + def makesquare(self, nums): + # 不能组成正方形的情况:1.火柴总长度不是4的倍数 2.火柴数少于4 3.最长的火柴大于目标边长 + sums = sum(nums) + if sums % 4 or len(nums) < 4: + return False + # 贪心,先排序可以节约回溯的次数 + nums.sort(reverse=True) + side_len = sums / 4 + if nums[0] > side_len: + return False + + def dfs(i, sides): + """ + 深度优先遍历 + :param i: 当前访问的火柴的位置 + :param sides: 当前4条边的长度 + :return: + """ + # 递归终止条件,火柴全部拼完 + if i == len(nums): + return True + # 尝试把火柴拼到4条边中 + for j in range(4): + # 当前边长加上新的火柴后长度小于等于目标边长。当前边长与前一边长相等时可跳过,以为如果前一边长失败,当前边长也会失败 + if sides[j] + nums[i] <= side_len and (j == 0 or sides[j] != sides[j - 1]): + # 放入当前火柴 + sides[j] += nums[i] + # 放入下一根火柴 + if dfs(i + 1, sides): + return True + # 放入失败,取出火柴准备放入下一条边 + sides[j] -= nums[i] + # 四条边都不能放火柴,回溯 + return False + # 初始化边并从0开始放入 return dfs(0, [0, 0, 0, 0]) \ No newline at end of file diff --git "a/leetcode/476.\346\225\260\345\255\227\347\232\204\350\241\245\346\225\260.py" "b/leetcode_Python/476.\346\225\260\345\255\227\347\232\204\350\241\245\346\225\260.py" similarity index 96% rename from "leetcode/476.\346\225\260\345\255\227\347\232\204\350\241\245\346\225\260.py" rename to "leetcode_Python/476.\346\225\260\345\255\227\347\232\204\350\241\245\346\225\260.py" index 38d6131..a033608 100644 --- "a/leetcode/476.\346\225\260\345\255\227\347\232\204\350\241\245\346\225\260.py" +++ "b/leetcode_Python/476.\346\225\260\345\255\227\347\232\204\350\241\245\346\225\260.py" @@ -1,18 +1,18 @@ -# 方法一:判断字符,添加相反字符 -class Solution(object): - def findComplement(self, num): - res = '' - for i in str(bin(num)[2:]): - if i == '1': - res += '0' - else: - res += '1' - return int(res, 2) - -# 方法二:逐位异或 -class Solution(object): - def findComplement(self, num): - res = '' - for i in bin(num)[2:]: - res += str(int(i)^1) +# 方法一:判断字符,添加相反字符 +class Solution(object): + def findComplement(self, num): + res = '' + for i in str(bin(num)[2:]): + if i == '1': + res += '0' + else: + res += '1' + return int(res, 2) + +# 方法二:逐位异或 +class Solution(object): + def findComplement(self, num): + res = '' + for i in bin(num)[2:]: + res += str(int(i)^1) return int(res, 2) \ No newline at end of file diff --git "a/leetcode/482.\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" "b/leetcode_Python/482.\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" similarity index 97% rename from "leetcode/482.\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" rename to "leetcode_Python/482.\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" index 72db6f1..ddb65d5 100644 --- "a/leetcode/482.\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" +++ "b/leetcode_Python/482.\345\257\206\351\222\245\346\240\274\345\274\217\345\214\226.py" @@ -1,27 +1,27 @@ -# 方法一:从后往前遍历,每K个字符添加1个'-',再判断最后是否刚好满K个多加了1个'-',若有需要去掉 -class Solution(object): - def licenseKeyFormatting(self, S, K): - res = '' - count = 0 - for s in reversed(S): - if s != '-': - res += s.upper() - count += 1 - if count == K: - res += '-' - count = 0 - if res and res[-1] == '-': - res = res[:-1] - return res[::-1] - -# 方法二:将'-'以外的全部字符个数与K取余计算得出第一组字符的个数,其他则每K个一组 -class Solution(object): - def licenseKeyFormatting(self, S, K): - res = [] - s = ''.join(S.split('-')).upper() - N = len(s) - if N%K != 0: - res.append(s[:N%K]) - for i in range(N%K, N, K): - res.append(s[i:i+K]) - return '-'.join(res) +# 方法一:从后往前遍历,每K个字符添加1个'-',再判断最后是否刚好满K个多加了1个'-',若有需要去掉 +class Solution(object): + def licenseKeyFormatting(self, S, K): + res = '' + count = 0 + for s in reversed(S): + if s != '-': + res += s.upper() + count += 1 + if count == K: + res += '-' + count = 0 + if res and res[-1] == '-': + res = res[:-1] + return res[::-1] + +# 方法二:将'-'以外的全部字符个数与K取余计算得出第一组字符的个数,其他则每K个一组 +class Solution(object): + def licenseKeyFormatting(self, S, K): + res = [] + s = ''.join(S.split('-')).upper() + N = len(s) + if N%K != 0: + res.append(s[:N%K]) + for i in range(N%K, N, K): + res.append(s[i:i+K]) + return '-'.join(res) diff --git "a/leetcode/485.\346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260.py" "b/leetcode_Python/485.\346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260.py" similarity index 97% rename from "leetcode/485.\346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260.py" rename to "leetcode_Python/485.\346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260.py" index 4037275..ab0108f 100644 --- "a/leetcode/485.\346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260.py" +++ "b/leetcode_Python/485.\346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260.py" @@ -1,16 +1,16 @@ -# 方法一:遍历统计连续1的个数,并更新最大值 -class Solution(object): - def findMaxConsecutiveOnes(self, nums): - max_count = count = 0 - for num in nums: - if num == 1: - count += 1 - max_count = max(max_count, count) - else: - count = 0 - return max_count - -# 方法二:按0切分出1的子串,计算最大长度 -class Solution(object): - def findMaxConsecutiveOnes(self, nums): +# 方法一:遍历统计连续1的个数,并更新最大值 +class Solution(object): + def findMaxConsecutiveOnes(self, nums): + max_count = count = 0 + for num in nums: + if num == 1: + count += 1 + max_count = max(max_count, count) + else: + count = 0 + return max_count + +# 方法二:按0切分出1的子串,计算最大长度 +class Solution(object): + def findMaxConsecutiveOnes(self, nums): return len(max(''.join(map(str, nums)).split('0'))) \ No newline at end of file diff --git "a/leetcode/492.\346\236\204\351\200\240\347\237\251\345\275\242.py" "b/leetcode_Python/492.\346\236\204\351\200\240\347\237\251\345\275\242.py" similarity index 97% rename from "leetcode/492.\346\236\204\351\200\240\347\237\251\345\275\242.py" rename to "leetcode_Python/492.\346\236\204\351\200\240\347\237\251\345\275\242.py" index 93b3090..3e69085 100644 --- "a/leetcode/492.\346\236\204\351\200\240\347\237\251\345\275\242.py" +++ "b/leetcode_Python/492.\346\236\204\351\200\240\347\237\251\345\275\242.py" @@ -1,6 +1,6 @@ -# 从长宽差距最小处开始判断,符合条件则返回 -class Solution(object): - def constructRectangle(self, area): - for i in range(int(math.sqrt(area)), 0, -1): - if area%i == 0: +# 从长宽差距最小处开始判断,符合条件则返回 +class Solution(object): + def constructRectangle(self, area): + for i in range(int(math.sqrt(area)), 0, -1): + if area%i == 0: return [area/i, i] \ No newline at end of file diff --git "a/leetcode/496.\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240I.py" "b/leetcode_Python/496.\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240I.py" similarity index 97% rename from "leetcode/496.\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240I.py" rename to "leetcode_Python/496.\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240I.py" index eed48f5..018d8db 100644 --- "a/leetcode/496.\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240I.py" +++ "b/leetcode_Python/496.\344\270\213\344\270\200\344\270\252\346\233\264\345\244\247\345\205\203\347\264\240I.py" @@ -1,12 +1,12 @@ -# 先用字典存放nums中每个元素后第一个比它大的值,再遍历findNums的元素从字典获取该值 -class Solution(object): - def nextGreaterElement(self, findNums, nums): - l = [] - d = {} - for num in nums: - while l and l[-1] < num: - d[l.pop()] = num - l.append(num) - for i in range(len(findNums)): - findNums[i] = d.get(findNums[i], -1) +# 先用字典存放nums中每个元素后第一个比它大的值,再遍历findNums的元素从字典获取该值 +class Solution(object): + def nextGreaterElement(self, findNums, nums): + l = [] + d = {} + for num in nums: + while l and l[-1] < num: + d[l.pop()] = num + l.append(num) + for i in range(len(findNums)): + findNums[i] = d.get(findNums[i], -1) return findNums \ No newline at end of file diff --git "a/leetcode/500.\351\224\256\347\233\230\350\241\214.py" "b/leetcode_Python/500.\351\224\256\347\233\230\350\241\214.py" similarity index 97% rename from "leetcode/500.\351\224\256\347\233\230\350\241\214.py" rename to "leetcode_Python/500.\351\224\256\347\233\230\350\241\214.py" index 94d77ec..27fbfe5 100644 --- "a/leetcode/500.\351\224\256\347\233\230\350\241\214.py" +++ "b/leetcode_Python/500.\351\224\256\347\233\230\350\241\214.py" @@ -1,16 +1,16 @@ -class Solution(object): - def findWords(self, words): - row1, row2, row3 = 'qwertyuiop', 'asdfghjkl', 'zxcvbnm' - res = [] - for word in words: - # 找出该单词第一个字母属于哪一行 - for r in [row1, row2, row3]: - if word[0].lower() in r: - row = r - # 遍历字母,如果有字母不在该行则退出,否则将单词添加到数组中 - for w in word: - if w.lower() not in row: - break - else: - res.append(word) +class Solution(object): + def findWords(self, words): + row1, row2, row3 = 'qwertyuiop', 'asdfghjkl', 'zxcvbnm' + res = [] + for word in words: + # 找出该单词第一个字母属于哪一行 + for r in [row1, row2, row3]: + if word[0].lower() in r: + row = r + # 遍历字母,如果有字母不在该行则退出,否则将单词添加到数组中 + for w in word: + if w.lower() not in row: + break + else: + res.append(word) return res \ No newline at end of file diff --git "a/leetcode/501.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\344\274\227\346\225\260.py" "b/leetcode_Python/501.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\344\274\227\346\225\260.py" similarity index 96% rename from "leetcode/501.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\344\274\227\346\225\260.py" rename to "leetcode_Python/501.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\344\274\227\346\225\260.py" index 07cfb56..c05d1dd 100644 --- "a/leetcode/501.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\344\274\227\346\225\260.py" +++ "b/leetcode_Python/501.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\344\274\227\346\225\260.py" @@ -1,24 +1,24 @@ -# 获取所有节点的值,再求众数 -import collections -class Solution(object): - def findMode(self, root): - if not root: - return [] - - # 中序遍历,得到结点值数组 - def inorder(root): - if root: - inorder(root.left) - l.append(root.val) - inorder(root.right) - - l = [] - inorder(root) - # 得到一个字典,每个结点值与其对应个数 - c = collections.Counter(l) - mode = max(c.values()) - res = [] - for key in c: - if c[key]==mode: - res.append(key) +# 获取所有节点的值,再求众数 +import collections +class Solution(object): + def findMode(self, root): + if not root: + return [] + + # 中序遍历,得到结点值数组 + def inorder(root): + if root: + inorder(root.left) + l.append(root.val) + inorder(root.right) + + l = [] + inorder(root) + # 得到一个字典,每个结点值与其对应个数 + c = collections.Counter(l) + mode = max(c.values()) + res = [] + for key in c: + if c[key]==mode: + res.append(key) return res \ No newline at end of file diff --git "a/leetcode/504.\344\270\203\350\277\233\345\210\266\346\225\260.py" "b/leetcode_Python/504.\344\270\203\350\277\233\345\210\266\346\225\260.py" similarity index 96% rename from "leetcode/504.\344\270\203\350\277\233\345\210\266\346\225\260.py" rename to "leetcode_Python/504.\344\270\203\350\277\233\345\210\266\346\225\260.py" index 639308c..259855c 100644 --- "a/leetcode/504.\344\270\203\350\277\233\345\210\266\346\225\260.py" +++ "b/leetcode_Python/504.\344\270\203\350\277\233\345\210\266\346\225\260.py" @@ -1,13 +1,13 @@ -# 除基取余,得到七进制数,再判断正负加上符号 -class Solution(object): - def convertToBase7(self, num): - if not num: - return '0' - res = '' - n = abs(num) - while n > 0: - res += str(n%7) - n /= 7 - if num < 0: - res += '-' +# 除基取余,得到七进制数,再判断正负加上符号 +class Solution(object): + def convertToBase7(self, num): + if not num: + return '0' + res = '' + n = abs(num) + while n > 0: + res += str(n%7) + n /= 7 + if num < 0: + res += '-' return res[::-1] \ No newline at end of file diff --git "a/leetcode/506.\347\233\270\345\257\271\345\220\215\346\254\241.py" "b/leetcode_Python/506.\347\233\270\345\257\271\345\220\215\346\254\241.py" similarity index 96% rename from "leetcode/506.\347\233\270\345\257\271\345\220\215\346\254\241.py" rename to "leetcode_Python/506.\347\233\270\345\257\271\345\220\215\346\254\241.py" index dd7e158..aff0d35 100644 --- "a/leetcode/506.\347\233\270\345\257\271\345\220\215\346\254\241.py" +++ "b/leetcode_Python/506.\347\233\270\345\257\271\345\220\215\346\254\241.py" @@ -1,21 +1,21 @@ -class Solution(object): - def findRelativeRanks(self, nums): - nums2 = nums[:] - nums2.sort(reverse=True) - d = {} - # 获取排序后的分数和名次,存入字典 - for i, v in enumerate(nums2): - d[v] = str(i+1) - - # 前三名改变值 - d[nums2[0]] = 'Gold Medal' - if len(nums2) > 1: - d[nums2[1]] = 'Silver Medal' - if len(nums2) > 2: - d[nums2[2]] = 'Bronze Medal' - - # 遍历原数组,获取对应的值存入新数组 - res = [] - for num in nums: - res.append(d[num]) +class Solution(object): + def findRelativeRanks(self, nums): + nums2 = nums[:] + nums2.sort(reverse=True) + d = {} + # 获取排序后的分数和名次,存入字典 + for i, v in enumerate(nums2): + d[v] = str(i+1) + + # 前三名改变值 + d[nums2[0]] = 'Gold Medal' + if len(nums2) > 1: + d[nums2[1]] = 'Silver Medal' + if len(nums2) > 2: + d[nums2[2]] = 'Bronze Medal' + + # 遍历原数组,获取对应的值存入新数组 + res = [] + for num in nums: + res.append(d[num]) return res \ No newline at end of file diff --git "a/leetcode/507.\345\256\214\347\276\216\346\225\260.py" "b/leetcode_Python/507.\345\256\214\347\276\216\346\225\260.py" similarity index 97% rename from "leetcode/507.\345\256\214\347\276\216\346\225\260.py" rename to "leetcode_Python/507.\345\256\214\347\276\216\346\225\260.py" index cd40a83..8755ffb 100644 --- "a/leetcode/507.\345\256\214\347\276\216\346\225\260.py" +++ "b/leetcode_Python/507.\345\256\214\347\276\216\346\225\260.py" @@ -1,15 +1,15 @@ -# 方法一:将正因子相加判断是否等于给定的正整数 -class Solution(object): - def checkPerfectNumber(self, num): - if num <= 1: - return False - sum = 1 - for i in range(2, int(math.sqrt(num))+1): - if num%i == 0: - sum += (i + num/i) - return num == sum - -# 方法二:1e8以内只有5个完美数 -class Solution(object): - def checkPerfectNumber(self, num): +# 方法一:将正因子相加判断是否等于给定的正整数 +class Solution(object): + def checkPerfectNumber(self, num): + if num <= 1: + return False + sum = 1 + for i in range(2, int(math.sqrt(num))+1): + if num%i == 0: + sum += (i + num/i) + return num == sum + +# 方法二:1e8以内只有5个完美数 +class Solution(object): + def checkPerfectNumber(self, num): return num in [6,28,496,8128,33550336] \ No newline at end of file diff --git "a/leetcode/508.\345\207\272\347\216\260\346\254\241\346\225\260\346\234\200\345\244\232\347\232\204\345\255\220\346\240\221\345\205\203\347\264\240\345\222\214.py" "b/leetcode_Python/508.\345\207\272\347\216\260\346\254\241\346\225\260\346\234\200\345\244\232\347\232\204\345\255\220\346\240\221\345\205\203\347\264\240\345\222\214.py" similarity index 97% rename from "leetcode/508.\345\207\272\347\216\260\346\254\241\346\225\260\346\234\200\345\244\232\347\232\204\345\255\220\346\240\221\345\205\203\347\264\240\345\222\214.py" rename to "leetcode_Python/508.\345\207\272\347\216\260\346\254\241\346\225\260\346\234\200\345\244\232\347\232\204\345\255\220\346\240\221\345\205\203\347\264\240\345\222\214.py" index c62299a..ad7b8ca 100644 --- "a/leetcode/508.\345\207\272\347\216\260\346\254\241\346\225\260\346\234\200\345\244\232\347\232\204\345\255\220\346\240\221\345\205\203\347\264\240\345\222\214.py" +++ "b/leetcode_Python/508.\345\207\272\347\216\260\346\254\241\346\225\260\346\234\200\345\244\232\347\232\204\345\255\220\346\240\221\345\205\203\347\264\240\345\222\214.py" @@ -1,25 +1,25 @@ -class Solution(object): - def findFrequentTreeSum(self, root): - if not root: - return [] - if not root.left and not root.right: - return [root.val] - # 字典用于存放子树和与对应次数 - d = dict() - - def treesum(root): - if not root: - return 0 - tsum = root.val - tsum += treesum(root.left) - tsum += treesum(root.right) - if not d.get(tsum): - d[tsum] = 1 - else: - d[tsum] += 1 - return tsum - - treesum(root) - # 按照次数由大到小排序 [(2,2),(-5,1)] - dsort = sorted(d.iteritems(), key=lambda x: x[1], reverse=True) - return [dsort[i][0] for i in range(len(dsort)) if dsort[i][1] == dsort[0][1]] +class Solution(object): + def findFrequentTreeSum(self, root): + if not root: + return [] + if not root.left and not root.right: + return [root.val] + # 字典用于存放子树和与对应次数 + d = dict() + + def treesum(root): + if not root: + return 0 + tsum = root.val + tsum += treesum(root.left) + tsum += treesum(root.right) + if not d.get(tsum): + d[tsum] = 1 + else: + d[tsum] += 1 + return tsum + + treesum(root) + # 按照次数由大到小排序 [(2,2),(-5,1)] + dsort = sorted(d.iteritems(), key=lambda x: x[1], reverse=True) + return [dsort[i][0] for i in range(len(dsort)) if dsort[i][1] == dsort[0][1]] diff --git "a/leetcode/513.\346\211\276\346\240\221\345\267\246\344\270\213\350\247\222\347\232\204\345\200\274.py" "b/leetcode_Python/513.\346\211\276\346\240\221\345\267\246\344\270\213\350\247\222\347\232\204\345\200\274.py" similarity index 97% rename from "leetcode/513.\346\211\276\346\240\221\345\267\246\344\270\213\350\247\222\347\232\204\345\200\274.py" rename to "leetcode_Python/513.\346\211\276\346\240\221\345\267\246\344\270\213\350\247\222\347\232\204\345\200\274.py" index fa10643..7d15690 100644 --- "a/leetcode/513.\346\211\276\346\240\221\345\267\246\344\270\213\350\247\222\347\232\204\345\200\274.py" +++ "b/leetcode_Python/513.\346\211\276\346\240\221\345\267\246\344\270\213\350\247\222\347\232\204\345\200\274.py" @@ -1,16 +1,16 @@ -# 层次遍历,返回最后一层第一个元素 -class Solution(object): - def findBottomLeftValue(self, root): - if not root: - return [] - res, cur_level, next_level, cur_val = [], [root], [], [] - while cur_level: - for node in cur_level: - cur_val.append(node.val) - if node.left: - next_level.append(node.left) - if node.right: - next_level.append(node.right) - res.append(cur_val) - cur_level, next_level, cur_val = next_level, [], [] +# 层次遍历,返回最后一层第一个元素 +class Solution(object): + def findBottomLeftValue(self, root): + if not root: + return [] + res, cur_level, next_level, cur_val = [], [root], [], [] + while cur_level: + for node in cur_level: + cur_val.append(node.val) + if node.left: + next_level.append(node.left) + if node.right: + next_level.append(node.right) + res.append(cur_val) + cur_level, next_level, cur_val = next_level, [], [] return res[-1][0] \ No newline at end of file diff --git "a/leetcode/515.\345\234\250\346\257\217\344\270\252\346\240\221\350\241\214\344\270\255\346\211\276\346\234\200\345\244\247\345\200\274.py" "b/leetcode_Python/515.\345\234\250\346\257\217\344\270\252\346\240\221\350\241\214\344\270\255\346\211\276\346\234\200\345\244\247\345\200\274.py" similarity index 97% rename from "leetcode/515.\345\234\250\346\257\217\344\270\252\346\240\221\350\241\214\344\270\255\346\211\276\346\234\200\345\244\247\345\200\274.py" rename to "leetcode_Python/515.\345\234\250\346\257\217\344\270\252\346\240\221\350\241\214\344\270\255\346\211\276\346\234\200\345\244\247\345\200\274.py" index a34e931..17f0f96 100644 --- "a/leetcode/515.\345\234\250\346\257\217\344\270\252\346\240\221\350\241\214\344\270\255\346\211\276\346\234\200\345\244\247\345\200\274.py" +++ "b/leetcode_Python/515.\345\234\250\346\257\217\344\270\252\346\240\221\350\241\214\344\270\255\346\211\276\346\234\200\345\244\247\345\200\274.py" @@ -1,16 +1,16 @@ -# 层次遍历,res数组添加每一行的最大值 -class Solution(object): - def largestValues(self, root): - if not root: - return [] - res, cur_level, next_level, cur_val = [], [root], [], [] - while cur_level: - for node in cur_level: - cur_val.append(node.val) - if node.left: - next_level.append(node.left) - if node.right: - next_level.append(node.right) - res.append(max(cur_val)) - cur_level, next_level, cur_val = next_level, [], [] +# 层次遍历,res数组添加每一行的最大值 +class Solution(object): + def largestValues(self, root): + if not root: + return [] + res, cur_level, next_level, cur_val = [], [root], [], [] + while cur_level: + for node in cur_level: + cur_val.append(node.val) + if node.left: + next_level.append(node.left) + if node.right: + next_level.append(node.right) + res.append(max(cur_val)) + cur_level, next_level, cur_val = next_level, [], [] return res \ No newline at end of file diff --git "a/leetcode/516.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" "b/leetcode_Python/516.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" similarity index 97% rename from "leetcode/516.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" rename to "leetcode_Python/516.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" index b7e73f6..7aec78e 100644 --- "a/leetcode/516.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" +++ "b/leetcode_Python/516.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.py" @@ -1,55 +1,55 @@ -# 动态规划:1、大问题分解成小问题 2、重复利用之前的计算结果 - -# dp[i][j]存放以s[i]开头、s[j]结尾的子串的最长回文子序列长度 -# 先计算相邻两个字符的最长回文长度,利用前面的结果再计算相邻三个字符,以此类推得到整个字符串的结果 -class Solution(object): - def longestPalindromeSubseq(self, s): - n = len(s) - dp = [[0]*n for _ in range(n)] - # 初始化数组 - for i in range(n): - dp[i][i] = 1 - for j in range(1, n): - for i in range(j-1, -1, -1): - if s[i] == s[j]: - # 回文串每次增加2个字符,所以需要在上一状态加2 - dp[i][j] = dp[i+1][j-1] + 2 - else: - # 若不相等则需要在其两个最长子串中比较出回文子序列长度较大者 - dp[i][j] = max(dp[i+1][j], dp[i][j-1]) - return dp[0][-1] -# g 1 2 4 4 4 -# 0 o 2 2 2 2 -# 0 0 o 1 1 1 -# 0 0 0 g 1 1 -# 0 0 0 0 l 1 -# 0 0 0 0 0 e - - - -# 转化为求s和s[::-1]的最长公共子序列 -# dp[i][j]表示t子串增加字符t[i]、s子串增加字符s[j]后,两者最长公共子序列的长度 -class Solution2(object): - def longestPalindromeSubseq(self, s): - if s == s[::-1]: - return len(s) - n = len(s) - t = s[::-1] - dp = [[0]*(n+1) for _ in range(n+1)] - for i in range(n): - for j in range(n): - if t[i] == s[j]: - # 两字符相等,则当前状态为前一状态加1 - dp[i+1][j+1] = dp[i][j] + 1 - else: - # 两字符不相等,则比较没有哪个字符时长度较大 - dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]) - return dp[-1][-1] -# g o o g l e -# 0 0 0 0 0 0 0 -# e 0 0 0 0 0 0 1 -# l 0 0 0 0 0 1 1 -# g 0 1 1 1 1 1 1 -# o 0 1 2 2 2 2 2 -# o 0 1 2 3 3 3 3 -# g 0 1 2 3 4 4 4 +# 动态规划:1、大问题分解成小问题 2、重复利用之前的计算结果 + +# dp[i][j]存放以s[i]开头、s[j]结尾的子串的最长回文子序列长度 +# 先计算相邻两个字符的最长回文长度,利用前面的结果再计算相邻三个字符,以此类推得到整个字符串的结果 +class Solution(object): + def longestPalindromeSubseq(self, s): + n = len(s) + dp = [[0]*n for _ in range(n)] + # 初始化数组 + for i in range(n): + dp[i][i] = 1 + for j in range(1, n): + for i in range(j-1, -1, -1): + if s[i] == s[j]: + # 回文串每次增加2个字符,所以需要在上一状态加2 + dp[i][j] = dp[i+1][j-1] + 2 + else: + # 若不相等则需要在其两个最长子串中比较出回文子序列长度较大者 + dp[i][j] = max(dp[i+1][j], dp[i][j-1]) + return dp[0][-1] +# g 1 2 4 4 4 +# 0 o 2 2 2 2 +# 0 0 o 1 1 1 +# 0 0 0 g 1 1 +# 0 0 0 0 l 1 +# 0 0 0 0 0 e + + + +# 转化为求s和s[::-1]的最长公共子序列 +# dp[i][j]表示t子串增加字符t[i]、s子串增加字符s[j]后,两者最长公共子序列的长度 +class Solution2(object): + def longestPalindromeSubseq(self, s): + if s == s[::-1]: + return len(s) + n = len(s) + t = s[::-1] + dp = [[0]*(n+1) for _ in range(n+1)] + for i in range(n): + for j in range(n): + if t[i] == s[j]: + # 两字符相等,则当前状态为前一状态加1 + dp[i+1][j+1] = dp[i][j] + 1 + else: + # 两字符不相等,则比较没有哪个字符时长度较大 + dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]) + return dp[-1][-1] +# g o o g l e +# 0 0 0 0 0 0 0 +# e 0 0 0 0 0 0 1 +# l 0 0 0 0 0 1 1 +# g 0 1 1 1 1 1 1 +# o 0 1 2 2 2 2 2 +# o 0 1 2 3 3 3 3 +# g 0 1 2 3 4 4 4 diff --git "a/leetcode/520.\346\243\200\346\265\213\345\244\247\345\206\231\345\255\227\346\257\215.py" "b/leetcode_Python/520.\346\243\200\346\265\213\345\244\247\345\206\231\345\255\227\346\257\215.py" similarity index 96% rename from "leetcode/520.\346\243\200\346\265\213\345\244\247\345\206\231\345\255\227\346\257\215.py" rename to "leetcode_Python/520.\346\243\200\346\265\213\345\244\247\345\206\231\345\255\227\346\257\215.py" index 76eeab4..03cc84e 100644 --- "a/leetcode/520.\346\243\200\346\265\213\345\244\247\345\206\231\345\255\227\346\257\215.py" +++ "b/leetcode_Python/520.\346\243\200\346\265\213\345\244\247\345\206\231\345\255\227\346\257\215.py" @@ -1,14 +1,14 @@ -class Solution(object): - def detectCapitalUse(self, word): - big = small = 0 - for s in word: - if 'A' <= s <= 'Z': - big += 1 - if 'a' <= s <= 'z': - small += 1 - if big==0 or small==0: - return True - elif small and big==1 and 'A' <= word[0] <= 'Z': - return True - else: +class Solution(object): + def detectCapitalUse(self, word): + big = small = 0 + for s in word: + if 'A' <= s <= 'Z': + big += 1 + if 'a' <= s <= 'z': + small += 1 + if big==0 or small==0: + return True + elif small and big==1 and 'A' <= word[0] <= 'Z': + return True + else: return False \ No newline at end of file diff --git "a/leetcode/521.\346\234\200\351\225\277\347\211\271\346\256\212\345\272\217\345\210\227I.py" "b/leetcode_Python/521.\346\234\200\351\225\277\347\211\271\346\256\212\345\272\217\345\210\227I.py" similarity index 97% rename from "leetcode/521.\346\234\200\351\225\277\347\211\271\346\256\212\345\272\217\345\210\227I.py" rename to "leetcode_Python/521.\346\234\200\351\225\277\347\211\271\346\256\212\345\272\217\345\210\227I.py" index 7943399..37229b2 100644 --- "a/leetcode/521.\346\234\200\351\225\277\347\211\271\346\256\212\345\272\217\345\210\227I.py" +++ "b/leetcode_Python/521.\346\234\200\351\225\277\347\211\271\346\256\212\345\272\217\345\210\227I.py" @@ -1,6 +1,6 @@ -# 任何字符串为其自身的子序列 -class Solution(object): - def findLUSlength(self, a, b): - if a==b: - return -1 +# 任何字符串为其自身的子序列 +class Solution(object): + def findLUSlength(self, a, b): + if a==b: + return -1 return max(len(a), len(b)) \ No newline at end of file diff --git "a/leetcode/526.\344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.py" "b/leetcode_Python/526.\344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.py" similarity index 98% rename from "leetcode/526.\344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.py" rename to "leetcode_Python/526.\344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.py" index a6f6add..030db1e 100644 --- "a/leetcode/526.\344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.py" +++ "b/leetcode_Python/526.\344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.py" @@ -1,19 +1,19 @@ -class Solution(object): - def countArrangement(self, N): - # 参数:整数数组,输出数组 - def butty(nums, output): - # 终止条件,若输出数组满足条件则排列个数加1,返回空结束当前递归 - if len(output) == N: - self.res += 1 - return - # 遍历,递归,使得整数数组中每个元素都有机会成为输出数组的下一个元素 - for i in range(len(nums)): - # 剪枝条件 - if nums[i] % (len(output) + 1) == 0 or (len(output) + 1) % nums[i] == 0: - # 整数数组和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 - butty(nums[:i] + nums[i+1:], output + [nums[i]]) - - self.res = 0 - nums = list(range(1, N+1)) - butty(nums, []) +class Solution(object): + def countArrangement(self, N): + # 参数:整数数组,输出数组 + def butty(nums, output): + # 终止条件,若输出数组满足条件则排列个数加1,返回空结束当前递归 + if len(output) == N: + self.res += 1 + return + # 遍历,递归,使得整数数组中每个元素都有机会成为输出数组的下一个元素 + for i in range(len(nums)): + # 剪枝条件 + if nums[i] % (len(output) + 1) == 0 or (len(output) + 1) % nums[i] == 0: + # 整数数组和输出数组元素动态更新,调用递归逐步产生结果,递归完成后回溯,继续搜索下一个结果 + butty(nums[:i] + nums[i+1:], output + [nums[i]]) + + self.res = 0 + nums = list(range(1, N+1)) + butty(nums, []) return self.res \ No newline at end of file diff --git "a/leetcode/530.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.py" "b/leetcode_Python/530.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.py" similarity index 96% rename from "leetcode/530.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.py" rename to "leetcode_Python/530.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.py" index c3d81ae..7455b63 100644 --- "a/leetcode/530.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.py" +++ "b/leetcode_Python/530.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.py" @@ -1,28 +1,28 @@ -# root节点应该与左子树的最右结点最接近,或者右子树的最左结点 -class Solution(object): - def getMinimumDifference(self, root): - self.res = 0x3f3f3f3f - - def getLeftMax(root): - if not root: - return 0x3f3f3f3f - if not root.right: - return root.val - return getLeftMax(root.right) - - def getRightMin(root): - if not root: - return 0x3f3f3f3f - if not root.left: - return root.val - return getRightMin(root.left) - - def getMin(root): - if not root: - return - self.res = min(self.res, abs(root.val-getLeftMax(root.left)), abs(root.val-getRightMin(root.right))) - getMin(root.left) - getMin(root.right) - - getMin(root) +# root节点应该与左子树的最右结点最接近,或者右子树的最左结点 +class Solution(object): + def getMinimumDifference(self, root): + self.res = 0x3f3f3f3f + + def getLeftMax(root): + if not root: + return 0x3f3f3f3f + if not root.right: + return root.val + return getLeftMax(root.right) + + def getRightMin(root): + if not root: + return 0x3f3f3f3f + if not root.left: + return root.val + return getRightMin(root.left) + + def getMin(root): + if not root: + return + self.res = min(self.res, abs(root.val-getLeftMax(root.left)), abs(root.val-getRightMin(root.right))) + getMin(root.left) + getMin(root.right) + + getMin(root) return self.res \ No newline at end of file diff --git "a/leetcode/532.\346\225\260\347\273\204\344\270\255\347\232\204K-diff\346\225\260\345\257\271.py" "b/leetcode_Python/532.\346\225\260\347\273\204\344\270\255\347\232\204K-diff\346\225\260\345\257\271.py" similarity index 97% rename from "leetcode/532.\346\225\260\347\273\204\344\270\255\347\232\204K-diff\346\225\260\345\257\271.py" rename to "leetcode_Python/532.\346\225\260\347\273\204\344\270\255\347\232\204K-diff\346\225\260\345\257\271.py" index 537c699..02477dc 100644 --- "a/leetcode/532.\346\225\260\347\273\204\344\270\255\347\232\204K-diff\346\225\260\345\257\271.py" +++ "b/leetcode_Python/532.\346\225\260\347\273\204\344\270\255\347\232\204K-diff\346\225\260\345\257\271.py" @@ -1,13 +1,13 @@ -class Solution(object): - def findPairs(self, nums, k): - if k < 0: - return 0 - # 使用字典保存元素和个数 - d = collections.Counter(nums) - res = 0 - for num in d: - if num + k in d: - # 当k为0时该元素至少需要出现两次 - if (k == 0 and d[num] >= 2) or k != 0: - res += 1 +class Solution(object): + def findPairs(self, nums, k): + if k < 0: + return 0 + # 使用字典保存元素和个数 + d = collections.Counter(nums) + res = 0 + for num in d: + if num + k in d: + # 当k为0时该元素至少需要出现两次 + if (k == 0 and d[num] >= 2) or k != 0: + res += 1 return res \ No newline at end of file diff --git "a/leetcode/537.\345\244\215\346\225\260\344\271\230\346\263\225.py" "b/leetcode_Python/537.\345\244\215\346\225\260\344\271\230\346\263\225.py" similarity index 97% rename from "leetcode/537.\345\244\215\346\225\260\344\271\230\346\263\225.py" rename to "leetcode_Python/537.\345\244\215\346\225\260\344\271\230\346\263\225.py" index 3aa0712..b110e41 100644 --- "a/leetcode/537.\345\244\215\346\225\260\344\271\230\346\263\225.py" +++ "b/leetcode_Python/537.\345\244\215\346\225\260\344\271\230\346\263\225.py" @@ -1,8 +1,8 @@ -# 提取出数字,计算实部和虚部的值 -class Solution(object): - def complexNumberMultiply(self, a, b): - num1 = map(int, a[:-1].split('+')) - num2 = map(int, b[:-1].split('+')) - real = num1[0] * num2[0] - num1[1] * num2[1] - vir = num1[1] * num2[0] + num1[0] * num2[1] +# 提取出数字,计算实部和虚部的值 +class Solution(object): + def complexNumberMultiply(self, a, b): + num1 = map(int, a[:-1].split('+')) + num2 = map(int, b[:-1].split('+')) + real = num1[0] * num2[0] - num1[1] * num2[1] + vir = num1[1] * num2[0] + num1[0] * num2[1] return '%d+%di' %(real, vir) \ No newline at end of file diff --git "a/leetcode/538.\346\212\212\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\344\270\272\347\264\257\345\212\240\346\240\221.py" "b/leetcode_Python/538.\346\212\212\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\344\270\272\347\264\257\345\212\240\346\240\221.py" similarity index 97% rename from "leetcode/538.\346\212\212\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\344\270\272\347\264\257\345\212\240\346\240\221.py" rename to "leetcode_Python/538.\346\212\212\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\344\270\272\347\264\257\345\212\240\346\240\221.py" index bfed9bf..6a6476c 100644 --- "a/leetcode/538.\346\212\212\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\344\270\272\347\264\257\345\212\240\346\240\221.py" +++ "b/leetcode_Python/538.\346\212\212\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\344\270\272\347\264\257\345\212\240\346\240\221.py" @@ -1,15 +1,15 @@ -# 中序遍历,当前结点值加上其后面结点值的和 -class Solution(object): - def convertBST(self, root): - def inorder(root): - if not root: - return [] - return inorder(root.left) + [root] + inorder(root.right) - - nodes = inorder(root) - values = [node.val for node in nodes] - bigSum = sum(values) - for i in range(len(values)): - bigSum -= values[i] - nodes[i].val = values[i] + bigSum +# 中序遍历,当前结点值加上其后面结点值的和 +class Solution(object): + def convertBST(self, root): + def inorder(root): + if not root: + return [] + return inorder(root.left) + [root] + inorder(root.right) + + nodes = inorder(root) + values = [node.val for node in nodes] + bigSum = sum(values) + for i in range(len(values)): + bigSum -= values[i] + nodes[i].val = values[i] + bigSum return root \ No newline at end of file diff --git "a/leetcode/541.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262II.py" "b/leetcode_Python/541.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262II.py" similarity index 97% rename from "leetcode/541.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262II.py" rename to "leetcode_Python/541.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262II.py" index 6669608..f2755dd 100644 --- "a/leetcode/541.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262II.py" +++ "b/leetcode_Python/541.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262II.py" @@ -1,12 +1,12 @@ -# 每隔k个字符就翻转k个字符 -class Solution(object): - def reverseStr(self, s, k): - n = len(s) - for i in range(0, n, 2*k): - # 剩余少于 k 个字符,全部翻转 - if i + k >= n: - s = s[:i] + s[i:][::-1] - # 剩余多于于 k 个字符,翻转 k 个字符 - else: - s = s[:i] + s[i:i+k][::-1] + s[i+k:] +# 每隔k个字符就翻转k个字符 +class Solution(object): + def reverseStr(self, s, k): + n = len(s) + for i in range(0, n, 2*k): + # 剩余少于 k 个字符,全部翻转 + if i + k >= n: + s = s[:i] + s[i:][::-1] + # 剩余多于于 k 个字符,翻转 k 个字符 + else: + s = s[:i] + s[i:i+k][::-1] + s[i+k:] return s \ No newline at end of file diff --git "a/leetcode/542.01 \347\237\251\351\230\265.py" "b/leetcode_Python/542.01 \347\237\251\351\230\265.py" similarity index 97% rename from "leetcode/542.01 \347\237\251\351\230\265.py" rename to "leetcode_Python/542.01 \347\237\251\351\230\265.py" index 9bae429..1c03aee 100644 --- "a/leetcode/542.01 \347\237\251\351\230\265.py" +++ "b/leetcode_Python/542.01 \347\237\251\351\230\265.py" @@ -1,24 +1,24 @@ -class Solution(object): - def updateMatrix(self, matrix): - m, n = len(matrix), len(matrix[0]) - # 结果矩阵初始化为-1,表示未搜索 - q, res = [], [[-1]*n for _ in range(m)] - d = [(1, 0), (-1, 0), (0, 1), (0, -1)] - - # 从值为0开始搜索,将其添加到队列 - for i in range(m): - for j in range(n): - if matrix[i][j] == 0: - res[i][j] = 0 - q += [(i, j)] - - # 搜索四个方向 - for x, y in q: - for dx, dy in d: - nx, ny = x + dx, y + dy - # 将未搜索的区域赋值,值为上个区域值加1,并将新区域添加到队列中继续搜素偶 - if 0 <= nx < m and 0 <= ny < n and res[nx][ny] == -1: - res[nx][ny] = res[x][y] + 1 - q += [(nx, ny)] - +class Solution(object): + def updateMatrix(self, matrix): + m, n = len(matrix), len(matrix[0]) + # 结果矩阵初始化为-1,表示未搜索 + q, res = [], [[-1]*n for _ in range(m)] + d = [(1, 0), (-1, 0), (0, 1), (0, -1)] + + # 从值为0开始搜索,将其添加到队列 + for i in range(m): + for j in range(n): + if matrix[i][j] == 0: + res[i][j] = 0 + q += [(i, j)] + + # 搜索四个方向 + for x, y in q: + for dx, dy in d: + nx, ny = x + dx, y + dy + # 将未搜索的区域赋值,值为上个区域值加1,并将新区域添加到队列中继续搜素偶 + if 0 <= nx < m and 0 <= ny < n and res[nx][ny] == -1: + res[nx][ny] = res[x][y] + 1 + q += [(nx, ny)] + return res \ No newline at end of file diff --git "a/leetcode/543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.py" "b/leetcode_Python/543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.py" similarity index 97% rename from "leetcode/543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.py" rename to "leetcode_Python/543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.py" index 283cbfe..72fbcc1 100644 --- "a/leetcode/543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.py" +++ "b/leetcode_Python/543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.py" @@ -1,28 +1,28 @@ -# 与563题相似 -# 方法一 -class Solution(object): - def diameterOfBinaryTree(self, root): - if not root: - return 0 - # 对每一个结点求直径,得到长度最大的直径 - return max(self.maxDepth(root.left) + self.maxDepth(root.right), self.diameterOfBinaryTree(root.left), self.diameterOfBinaryTree(root.right)) - - # 求某结点为根时,该树的最大深度 - def maxDepth(self, root): - if not root: - return 0 - return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right)) - -# 方法二:边求深度,边更新res的值 -class Solution(object): - def diameterOfBinaryTree(self, root): - self.res = 0 - def maxDepth(root): - if not root: - return 0 - L = maxDepth(root.left) - R = maxDepth(root.right) - self.res = max(self.res, L+R) - return 1 + max(L, R) - maxDepth(root) +# 与563题相似 +# 方法一 +class Solution(object): + def diameterOfBinaryTree(self, root): + if not root: + return 0 + # 对每一个结点求直径,得到长度最大的直径 + return max(self.maxDepth(root.left) + self.maxDepth(root.right), self.diameterOfBinaryTree(root.left), self.diameterOfBinaryTree(root.right)) + + # 求某结点为根时,该树的最大深度 + def maxDepth(self, root): + if not root: + return 0 + return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right)) + +# 方法二:边求深度,边更新res的值 +class Solution(object): + def diameterOfBinaryTree(self, root): + self.res = 0 + def maxDepth(root): + if not root: + return 0 + L = maxDepth(root.left) + R = maxDepth(root.right) + self.res = max(self.res, L+R) + return 1 + max(L, R) + maxDepth(root) return self.res \ No newline at end of file diff --git "a/leetcode/547.\346\234\213\345\217\213\345\234\210.py" "b/leetcode_Python/547.\346\234\213\345\217\213\345\234\210.py" similarity index 96% rename from "leetcode/547.\346\234\213\345\217\213\345\234\210.py" rename to "leetcode_Python/547.\346\234\213\345\217\213\345\234\210.py" index 7c3f34d..6fedf90 100644 --- "a/leetcode/547.\346\234\213\345\217\213\345\234\210.py" +++ "b/leetcode_Python/547.\346\234\213\345\217\213\345\234\210.py" @@ -1,85 +1,85 @@ -# 深度优先搜索 -class Solution(object): - def findCircleNum(self, M): - m = len(M[0]) - visited = [0 for _ in range(m)] - count = 0 - - # 参数动态更新:当前好友、已访问数组 - def dfs(i): - # 当前好友状态置为已访问 - visited[i] = 1 - # 遍历所有人 - for j in range(m): - # 若两人是朋友并且其朋友未访问过 - if M[i][j] == 1 and visited[j] == 0: - # 递归遍历朋友的朋友 - dfs(j) - - # 遍历所有人 - for i in range(m): - # 若当前好友未访问过 - if visited[i] == 0: - # 则朋友圈个数加1 - count += 1 - # 深度优先搜索,递归遍历他的朋友 - dfs(i) - - return count - - -# 并查集 -class Solution2: - def findCircleNum(self, M): - m = len(M) - # 记录每个结点的父亲 - parent = [i for i in range(m)] - - # 查找 - def find(i): - # 根结点的父亲是自己,找到根结点,即找到代表元 - if i == parent[i]: - return i - return find(parent[i]) - - # 合并 - def union(i, j): - # 找到各自的根结点 - root_i, root_j = find(i), find(j) - # 将某一方根结点置为另一方根结点的父亲,即合并 - parent[root_j] = root_i - - for i in range(m): - for j in range(i+1): - if M[i][j]: - union(i,j) - - return len(set([find(i) for i in range(m)])) - - -# 并查集 -class Solution3(object): - def findCircleNum(self, M): - m = len(M) - # 用字典记录每个结点的父亲 - d = {} - - # 查找 - def find(x): - # x的父亲不是自己,即不是根结点 - while d[x] != x: - # 逐级往上找x的父亲的父亲 - x = d[d[x]] - # 返回根结点 - return x - - for i in range(m): - for j in range(i+1): - if M[i][j] == 1: - # 若字典有键i(1),则其值为键i(1)对应的值;否则设置键i(1)的值为i(2) - d.setdefault(i, i) - d.setdefault(j, j) - # 将某一方根结点置为另一方根结点的父亲,即合并 - d[find(i)] = find(j) - +# 深度优先搜索 +class Solution(object): + def findCircleNum(self, M): + m = len(M[0]) + visited = [0 for _ in range(m)] + count = 0 + + # 参数动态更新:当前好友、已访问数组 + def dfs(i): + # 当前好友状态置为已访问 + visited[i] = 1 + # 遍历所有人 + for j in range(m): + # 若两人是朋友并且其朋友未访问过 + if M[i][j] == 1 and visited[j] == 0: + # 递归遍历朋友的朋友 + dfs(j) + + # 遍历所有人 + for i in range(m): + # 若当前好友未访问过 + if visited[i] == 0: + # 则朋友圈个数加1 + count += 1 + # 深度优先搜索,递归遍历他的朋友 + dfs(i) + + return count + + +# 并查集 +class Solution2: + def findCircleNum(self, M): + m = len(M) + # 记录每个结点的父亲 + parent = [i for i in range(m)] + + # 查找 + def find(i): + # 根结点的父亲是自己,找到根结点,即找到代表元 + if i == parent[i]: + return i + return find(parent[i]) + + # 合并 + def union(i, j): + # 找到各自的根结点 + root_i, root_j = find(i), find(j) + # 将某一方根结点置为另一方根结点的父亲,即合并 + parent[root_j] = root_i + + for i in range(m): + for j in range(i+1): + if M[i][j]: + union(i,j) + + return len(set([find(i) for i in range(m)])) + + +# 并查集 +class Solution3(object): + def findCircleNum(self, M): + m = len(M) + # 用字典记录每个结点的父亲 + d = {} + + # 查找 + def find(x): + # x的父亲不是自己,即不是根结点 + while d[x] != x: + # 逐级往上找x的父亲的父亲 + x = d[d[x]] + # 返回根结点 + return x + + for i in range(m): + for j in range(i+1): + if M[i][j] == 1: + # 若字典有键i(1),则其值为键i(1)对应的值;否则设置键i(1)的值为i(2) + d.setdefault(i, i) + d.setdefault(j, j) + # 将某一方根结点置为另一方根结点的父亲,即合并 + d[find(i)] = find(j) + return len(set([find(x) for x in d])) \ No newline at end of file diff --git "a/leetcode/551.\345\255\246\347\224\237\345\207\272\345\213\244\350\256\260\345\275\225I.py" "b/leetcode_Python/551.\345\255\246\347\224\237\345\207\272\345\213\244\350\256\260\345\275\225I.py" similarity index 98% rename from "leetcode/551.\345\255\246\347\224\237\345\207\272\345\213\244\350\256\260\345\275\225I.py" rename to "leetcode_Python/551.\345\255\246\347\224\237\345\207\272\345\213\244\350\256\260\345\275\225I.py" index 6a2bbcb..2fb20d5 100644 --- "a/leetcode/551.\345\255\246\347\224\237\345\207\272\345\213\244\350\256\260\345\275\225I.py" +++ "b/leetcode_Python/551.\345\255\246\347\224\237\345\207\272\345\213\244\350\256\260\345\275\225I.py" @@ -1,3 +1,3 @@ -class Solution(object): - def checkRecord(self, s): +class Solution(object): + def checkRecord(self, s): return s.count('A')<=1 and s.count('LLL')==0 \ No newline at end of file diff --git "a/leetcode/553.\346\234\200\344\274\230\351\231\244\346\263\225.py" "b/leetcode_Python/553.\346\234\200\344\274\230\351\231\244\346\263\225.py" similarity index 97% rename from "leetcode/553.\346\234\200\344\274\230\351\231\244\346\263\225.py" rename to "leetcode_Python/553.\346\234\200\344\274\230\351\231\244\346\263\225.py" index e61f94b..e334cab 100644 --- "a/leetcode/553.\346\234\200\344\274\230\351\231\244\346\263\225.py" +++ "b/leetcode_Python/553.\346\234\200\344\274\230\351\231\244\346\263\225.py" @@ -1,7 +1,7 @@ -# 大于两个数时最优除法为a/(b/c/d....) -class Solution(object): - def optimalDivision(self, nums): - nums = map(str, nums) - if len(nums) <= 2: - return '/'.join(nums) +# 大于两个数时最优除法为a/(b/c/d....) +class Solution(object): + def optimalDivision(self, nums): + nums = map(str, nums) + if len(nums) <= 2: + return '/'.join(nums) return '{}/({})'.format(nums[0], '/'.join(nums[1:])) \ No newline at end of file diff --git "a/leetcode/557.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215III.py" "b/leetcode_Python/557.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215III.py" similarity index 97% rename from "leetcode/557.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215III.py" rename to "leetcode_Python/557.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215III.py" index 52c6021..3a36e83 100644 --- "a/leetcode/557.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215III.py" +++ "b/leetcode_Python/557.\345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\215\225\350\257\215III.py" @@ -1,10 +1,10 @@ -# 整体反转,再将单词位置反转 -class Solution(object): - def reverseWords(self, s): - words = s[::-1].split(' ')[::-1] - return ' '.join(word for word in words) - -# 先切分单词,在逐个单词反转 -class Solution(object): - def reverseWords(self, s): +# 整体反转,再将单词位置反转 +class Solution(object): + def reverseWords(self, s): + words = s[::-1].split(' ')[::-1] + return ' '.join(word for word in words) + +# 先切分单词,在逐个单词反转 +class Solution(object): + def reverseWords(self, s): return ' '.join(word[::-1] for word in s.split(' ')) \ No newline at end of file diff --git "a/leetcode/559.N\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.py" "b/leetcode_Python/559.N\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.py" similarity index 98% rename from "leetcode/559.N\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.py" rename to "leetcode_Python/559.N\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.py" index 6ba174e..9642247 100644 --- "a/leetcode/559.N\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.py" +++ "b/leetcode_Python/559.N\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.py" @@ -1,6 +1,6 @@ -# 一条路径上累加结点个数,取最大个数 -class Solution(object): - def maxDepth(self, root): - if not root: - return 0 +# 一条路径上累加结点个数,取最大个数 +class Solution(object): + def maxDepth(self, root): + if not root: + return 0 return 1 + max([self.maxDepth(child) for child in root.children]) if root.children else 1 \ No newline at end of file diff --git "a/leetcode/561.\346\225\260\347\273\204\346\213\206\345\210\206I.py" "b/leetcode_Python/561.\346\225\260\347\273\204\346\213\206\345\210\206I.py" similarity index 97% rename from "leetcode/561.\346\225\260\347\273\204\346\213\206\345\210\206I.py" rename to "leetcode_Python/561.\346\225\260\347\273\204\346\213\206\345\210\206I.py" index ecee816..5c598b9 100644 --- "a/leetcode/561.\346\225\260\347\273\204\346\213\206\345\210\206I.py" +++ "b/leetcode_Python/561.\346\225\260\347\273\204\346\213\206\345\210\206I.py" @@ -1,5 +1,5 @@ -# 将索引为偶数的值累加 -class Solution(object): - def arrayPairSum(self, nums): - nums.sort() +# 将索引为偶数的值累加 +class Solution(object): + def arrayPairSum(self, nums): + nums.sort() return sum(nums[::2]) \ No newline at end of file diff --git "a/leetcode/563.\344\272\214\345\217\211\346\240\221\347\232\204\345\235\241\345\272\246.py" "b/leetcode_Python/563.\344\272\214\345\217\211\346\240\221\347\232\204\345\235\241\345\272\246.py" similarity index 97% rename from "leetcode/563.\344\272\214\345\217\211\346\240\221\347\232\204\345\235\241\345\272\246.py" rename to "leetcode_Python/563.\344\272\214\345\217\211\346\240\221\347\232\204\345\235\241\345\272\246.py" index 509d4b1..4a1d5bb 100644 --- "a/leetcode/563.\344\272\214\345\217\211\346\240\221\347\232\204\345\235\241\345\272\246.py" +++ "b/leetcode_Python/563.\344\272\214\345\217\211\346\240\221\347\232\204\345\235\241\345\272\246.py" @@ -1,28 +1,28 @@ -# 与543题相似 -# 方法一 -class Solution(object): - def findTilt(self, root): - if not root: - return 0 - # 对每一个结点求坡度 - return abs(self.nodeSum(root.left) - self.nodeSum(root.right)) + self.findTilt(root.left) + self.findTilt(root.right) - - # 求某结点为根时,该树的结点之和 - def nodeSum(self, root): - if not root: - return 0 - return root.val + self.nodeSum(root.left) + self.nodeSum(root.right) - -# 方法二:边求坡度,边更新res的值 -class Solution(object): - def findTilt(self, root): - self.res = 0 - def nodeSum(root): - if not root: - return 0 - left_sum = nodeSum(root.left) - right_sum = nodeSum(root.right) - self.res += abs(left_sum - right_sum) - return root.val + left_sum + right_sum - nodeSum(root) +# 与543题相似 +# 方法一 +class Solution(object): + def findTilt(self, root): + if not root: + return 0 + # 对每一个结点求坡度 + return abs(self.nodeSum(root.left) - self.nodeSum(root.right)) + self.findTilt(root.left) + self.findTilt(root.right) + + # 求某结点为根时,该树的结点之和 + def nodeSum(self, root): + if not root: + return 0 + return root.val + self.nodeSum(root.left) + self.nodeSum(root.right) + +# 方法二:边求坡度,边更新res的值 +class Solution(object): + def findTilt(self, root): + self.res = 0 + def nodeSum(root): + if not root: + return 0 + left_sum = nodeSum(root.left) + right_sum = nodeSum(root.right) + self.res += abs(left_sum - right_sum) + return root.val + left_sum + right_sum + nodeSum(root) return self.res \ No newline at end of file diff --git "a/leetcode/566.\351\207\215\345\241\221\347\237\251\351\230\265.py" "b/leetcode_Python/566.\351\207\215\345\241\221\347\237\251\351\230\265.py" similarity index 96% rename from "leetcode/566.\351\207\215\345\241\221\347\237\251\351\230\265.py" rename to "leetcode_Python/566.\351\207\215\345\241\221\347\237\251\351\230\265.py" index 12cc3c4..5b9f56a 100644 --- "a/leetcode/566.\351\207\215\345\241\221\347\237\251\351\230\265.py" +++ "b/leetcode_Python/566.\351\207\215\345\241\221\347\237\251\351\230\265.py" @@ -1,20 +1,20 @@ -# 先将矩阵所有值添加到数组中,再将数组中的值添加到新的矩阵中 -class Solution(object): - def matrixReshape(self, nums, r, c): - row = len(nums) - col = len(nums[0]) - - if row*col < r*c: - return nums - - t = [] - for i in range(row): - for j in range(col): - t.append(nums[i][j]) - - res = [] - m = 0 - for i in range(r): - res.append(t[m:m+c]) - m += c +# 先将矩阵所有值添加到数组中,再将数组中的值添加到新的矩阵中 +class Solution(object): + def matrixReshape(self, nums, r, c): + row = len(nums) + col = len(nums[0]) + + if row*col < r*c: + return nums + + t = [] + for i in range(row): + for j in range(col): + t.append(nums[i][j]) + + res = [] + m = 0 + for i in range(r): + res.append(t[m:m+c]) + m += c return res \ No newline at end of file diff --git "a/leetcode/572.\345\217\246\344\270\200\344\270\252\346\240\221\347\232\204\345\255\220\346\240\221.py" "b/leetcode_Python/572.\345\217\246\344\270\200\344\270\252\346\240\221\347\232\204\345\255\220\346\240\221.py" similarity index 97% rename from "leetcode/572.\345\217\246\344\270\200\344\270\252\346\240\221\347\232\204\345\255\220\346\240\221.py" rename to "leetcode_Python/572.\345\217\246\344\270\200\344\270\252\346\240\221\347\232\204\345\255\220\346\240\221.py" index a774b55..e539ffe 100644 --- "a/leetcode/572.\345\217\246\344\270\200\344\270\252\346\240\221\347\232\204\345\255\220\346\240\221.py" +++ "b/leetcode_Python/572.\345\217\246\344\270\200\344\270\252\346\240\221\347\232\204\345\255\220\346\240\221.py" @@ -1,16 +1,16 @@ -class Solution(object): - def isSubtree(self, s, t): - if not t: - return True - if not s and t: - return False - # 判断不同结点作为根结点的树是否与给定树相同 - return self.isSametree(s, t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t) - - # 方法作用:判断给定的两个结点是否相同。递归后变成判断两棵树是否相同 - def isSametree(self, p, q): - if not p and not q: - return True - if (not p and q) or (p and not q): - return False +class Solution(object): + def isSubtree(self, s, t): + if not t: + return True + if not s and t: + return False + # 判断不同结点作为根结点的树是否与给定树相同 + return self.isSametree(s, t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t) + + # 方法作用:判断给定的两个结点是否相同。递归后变成判断两棵树是否相同 + def isSametree(self, p, q): + if not p and not q: + return True + if (not p and q) or (p and not q): + return False return p.val==q.val and self.isSametree(p.left, q.left) and self.isSametree(p.right, q.right) \ No newline at end of file diff --git "a/leetcode/575.\345\210\206\347\263\226\346\236\234.py" "b/leetcode_Python/575.\345\210\206\347\263\226\346\236\234.py" similarity index 98% rename from "leetcode/575.\345\210\206\347\263\226\346\236\234.py" rename to "leetcode_Python/575.\345\210\206\347\263\226\346\236\234.py" index 22ec6f1..8df2fa5 100644 --- "a/leetcode/575.\345\210\206\347\263\226\346\236\234.py" +++ "b/leetcode_Python/575.\345\210\206\347\263\226\346\236\234.py" @@ -1,4 +1,4 @@ -# 分到的糖果个数和糖果的种类数取较小者 -class Solution(object): - def distributeCandies(self, candies): +# 分到的糖果个数和糖果的种类数取较小者 +class Solution(object): + def distributeCandies(self, candies): return min(len(candies)/2, len(set(candies))) \ No newline at end of file diff --git "a/leetcode/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" "b/leetcode_Python/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" similarity index 97% rename from "leetcode/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" rename to "leetcode_Python/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" index 38ba3ad..eacc9c6 100644 --- "a/leetcode/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" +++ "b/leetcode_Python/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" @@ -1,13 +1,13 @@ -# 将原数组排序后,从左右两边的元素开始与排序后的数组比较,得到左边两边第一个不相同的元素的索引,相减得到区间长度 -class Solution(object): - def findUnsortedSubarray(self, nums): - nums2 = sorted(nums) - i, j = 0, len(nums)-1 - while i < j: - if nums[i] == nums2[i]: - i += 1 - elif nums[j] == nums2[j]: - j -= 1 - else: - return j-i+1 +# 将原数组排序后,从左右两边的元素开始与排序后的数组比较,得到左边两边第一个不相同的元素的索引,相减得到区间长度 +class Solution(object): + def findUnsortedSubarray(self, nums): + nums2 = sorted(nums) + i, j = 0, len(nums)-1 + while i < j: + if nums[i] == nums2[i]: + i += 1 + elif nums[j] == nums2[j]: + j -= 1 + else: + return j-i+1 return 0 \ No newline at end of file diff --git "a/leetcode/589.N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" "b/leetcode_Python/589.N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" similarity index 96% rename from "leetcode/589.N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" rename to "leetcode_Python/589.N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" index 8641c43..428784c 100644 --- "a/leetcode/589.N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" +++ "b/leetcode_Python/589.N\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.py" @@ -1,23 +1,23 @@ -# 方法一:递归 -class Solution(object): - - def preorder(self, root): - res = [] - if root: - res.append(root.val) - for child in root.children: - res += self.preorder(child) - return res - -# 方法二:迭代 -class Solution(object): - def preorder(self, root): - if not root: - return [] - res, stack = [], [root] - while stack: - node = stack.pop() - res.append(node.val) - for child in node.children[::-1]: - stack.append(child) +# 方法一:递归 +class Solution(object): + + def preorder(self, root): + res = [] + if root: + res.append(root.val) + for child in root.children: + res += self.preorder(child) + return res + +# 方法二:迭代 +class Solution(object): + def preorder(self, root): + if not root: + return [] + res, stack = [], [root] + while stack: + node = stack.pop() + res.append(node.val) + for child in node.children[::-1]: + stack.append(child) return res \ No newline at end of file diff --git "a/leetcode/590.N\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" "b/leetcode_Python/590.N\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" similarity index 96% rename from "leetcode/590.N\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" rename to "leetcode_Python/590.N\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" index b416bea..2807886 100644 --- "a/leetcode/590.N\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" +++ "b/leetcode_Python/590.N\345\217\211\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206.py" @@ -1,22 +1,22 @@ -# 方法一:递归 -class Solution(object): - def postorder(self, root): - res = [] - if root: - for child in root.children: - res += self.postorder(child) - res.append(root.val) - return res - -# 方法二:迭代 -class Solution(object): - def postorder(self, root): - if not root: - return [] - res, stack = [], [root] - while stack: - node = stack.pop() - res.append(node.val) - for child in node.children: - stack.append(child) +# 方法一:递归 +class Solution(object): + def postorder(self, root): + res = [] + if root: + for child in root.children: + res += self.postorder(child) + res.append(root.val) + return res + +# 方法二:迭代 +class Solution(object): + def postorder(self, root): + if not root: + return [] + res, stack = [], [root] + while stack: + node = stack.pop() + res.append(node.val) + for child in node.children: + stack.append(child) return res[::-1] \ No newline at end of file diff --git "a/leetcode/594.\346\234\200\351\225\277\345\222\214\350\260\220\345\255\220\345\272\217\345\210\227.py" "b/leetcode_Python/594.\346\234\200\351\225\277\345\222\214\350\260\220\345\255\220\345\272\217\345\210\227.py" similarity index 97% rename from "leetcode/594.\346\234\200\351\225\277\345\222\214\350\260\220\345\255\220\345\272\217\345\210\227.py" rename to "leetcode_Python/594.\346\234\200\351\225\277\345\222\214\350\260\220\345\255\220\345\272\217\345\210\227.py" index b291544..28cc9a1 100644 --- "a/leetcode/594.\346\234\200\351\225\277\345\222\214\350\260\220\345\255\220\345\272\217\345\210\227.py" +++ "b/leetcode_Python/594.\346\234\200\351\225\277\345\222\214\350\260\220\345\255\220\345\272\217\345\210\227.py" @@ -1,10 +1,10 @@ -# 相邻两个元素的出现次数最大和即为最长和谐子序列 -class Solution(object): - def findLHS(self, nums): - d = collections.Counter(nums) - l = sorted(list(set(nums))) - count = 0 - for i in range(len(l)-1): - if l[i]+1 == l[i+1] and d[l[i]] + d[l[i+1]] > count: - count = d[l[i]] + d[l[i+1]] +# 相邻两个元素的出现次数最大和即为最长和谐子序列 +class Solution(object): + def findLHS(self, nums): + d = collections.Counter(nums) + l = sorted(list(set(nums))) + count = 0 + for i in range(len(l)-1): + if l[i]+1 == l[i+1] and d[l[i]] + d[l[i+1]] > count: + count = d[l[i]] + d[l[i+1]] return count \ No newline at end of file diff --git "a/leetcode/598.\350\214\203\345\233\264\346\261\202\345\222\214 II.py" "b/leetcode_Python/598.\350\214\203\345\233\264\346\261\202\345\222\214 II.py" similarity index 96% rename from "leetcode/598.\350\214\203\345\233\264\346\261\202\345\222\214 II.py" rename to "leetcode_Python/598.\350\214\203\345\233\264\346\261\202\345\222\214 II.py" index dc992a4..3c31b1f 100644 --- "a/leetcode/598.\350\214\203\345\233\264\346\261\202\345\222\214 II.py" +++ "b/leetcode_Python/598.\350\214\203\345\233\264\346\261\202\345\222\214 II.py" @@ -1,9 +1,9 @@ -# 找最小重叠部分的行列数相乘 -class Solution(object): - def maxCount(self, m, n, ops): - for op in ops: - if op[0] < m: - m = op[0] - if op[1] < n: - n = op[1] +# 找最小重叠部分的行列数相乘 +class Solution(object): + def maxCount(self, m, n, ops): + for op in ops: + if op[0] < m: + m = op[0] + if op[1] < n: + n = op[1] return m*n \ No newline at end of file diff --git "a/leetcode/599.\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" "b/leetcode_Python/599.\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" similarity index 97% rename from "leetcode/599.\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" rename to "leetcode_Python/599.\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" index 2bd6a3a..9f37a41 100644 --- "a/leetcode/599.\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" +++ "b/leetcode_Python/599.\344\270\244\344\270\252\345\210\227\350\241\250\347\232\204\346\234\200\345\260\217\347\264\242\345\274\225\346\200\273\345\222\214.py" @@ -1,8 +1,8 @@ -# 先将共同字符串的索引和存入字典,再找出索引和最小的字符串 -class Solution(object): - def findRestaurant(self, list1, list2): - d = {} - for l in list1: - if l in list2: - d[l] = list1.index(l) + list2.index(l) +# 先将共同字符串的索引和存入字典,再找出索引和最小的字符串 +class Solution(object): + def findRestaurant(self, list1, list2): + d = {} + for l in list1: + if l in list2: + d[l] = list1.index(l) + list2.index(l) return [key for key in d if d[key]==min(d.values())] \ No newline at end of file diff --git "a/leetcode/605.\347\247\215\350\212\261\351\227\256\351\242\230.py" "b/leetcode_Python/605.\347\247\215\350\212\261\351\227\256\351\242\230.py" similarity index 97% rename from "leetcode/605.\347\247\215\350\212\261\351\227\256\351\242\230.py" rename to "leetcode_Python/605.\347\247\215\350\212\261\351\227\256\351\242\230.py" index f83ea36..00e2e05 100644 --- "a/leetcode/605.\347\247\215\350\212\261\351\227\256\351\242\230.py" +++ "b/leetcode_Python/605.\347\247\215\350\212\261\351\227\256\351\242\230.py" @@ -1,30 +1,30 @@ -class Solution(object): - def canPlaceFlowers(self, flowerbed, n): - if not n: - return True - - lens = len(flowerbed) - i = 0 - while i < lens: - # 当前为0,前一个已经为0,只需判断后一个是否为0 - if flowerbed[i] == 0: - # 后一个为0,则当前可种花,走两步判断下一个位置 - if i < lens-1 and flowerbed[i+1] == 0: - n -= 1 - if not n: - break - i += 2 - # 后一个为1,则当前不可种花,走三步判断下一个位置 - elif i < lens-1 and flowerbed[i+1] == 1: - i += 3 - # 当前是最后一个,由于前面是0,故当前可种花 - elif i == lens-1: - n -= 1 - break - # 当前为1, 1后肯定是0,走两步判断下一个位置 - else: - i += 2 - - if not n: - return True +class Solution(object): + def canPlaceFlowers(self, flowerbed, n): + if not n: + return True + + lens = len(flowerbed) + i = 0 + while i < lens: + # 当前为0,前一个已经为0,只需判断后一个是否为0 + if flowerbed[i] == 0: + # 后一个为0,则当前可种花,走两步判断下一个位置 + if i < lens-1 and flowerbed[i+1] == 0: + n -= 1 + if not n: + break + i += 2 + # 后一个为1,则当前不可种花,走三步判断下一个位置 + elif i < lens-1 and flowerbed[i+1] == 1: + i += 3 + # 当前是最后一个,由于前面是0,故当前可种花 + elif i == lens-1: + n -= 1 + break + # 当前为1, 1后肯定是0,走两步判断下一个位置 + else: + i += 2 + + if not n: + return True return False \ No newline at end of file diff --git "a/leetcode/606.\346\240\271\346\215\256\344\272\214\345\217\211\346\240\221\345\210\233\345\273\272\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/606.\346\240\271\346\215\256\344\272\214\345\217\211\346\240\221\345\210\233\345\273\272\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "leetcode/606.\346\240\271\346\215\256\344\272\214\345\217\211\346\240\221\345\210\233\345\273\272\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/606.\346\240\271\346\215\256\344\272\214\345\217\211\346\240\221\345\210\233\345\273\272\345\255\227\347\254\246\344\270\262.py" index f18edc7..2d44471 100644 --- "a/leetcode/606.\346\240\271\346\215\256\344\272\214\345\217\211\346\240\221\345\210\233\345\273\272\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/606.\346\240\271\346\215\256\344\272\214\345\217\211\346\240\221\345\210\233\345\273\272\345\255\227\347\254\246\344\270\262.py" @@ -1,14 +1,14 @@ -class Solution(object): - def tree2str(self, t): - if not t: - return '' - res = str(t.val) - if t.left and t.right: - return res + '(' + self.tree2str(t.left) + ')' + '(' + self.tree2str(t.right) + ')' - # 可省略空括号 - if t.left and not t.right: - return res + '(' + self.tree2str(t.left) + ')' - # 不可省略空括号 - if not t.left and t.right: - return res + '()(' + self.tree2str(t.right) + ')' +class Solution(object): + def tree2str(self, t): + if not t: + return '' + res = str(t.val) + if t.left and t.right: + return res + '(' + self.tree2str(t.left) + ')' + '(' + self.tree2str(t.right) + ')' + # 可省略空括号 + if t.left and not t.right: + return res + '(' + self.tree2str(t.left) + ')' + # 不可省略空括号 + if not t.left and t.right: + return res + '()(' + self.tree2str(t.right) + ')' return res \ No newline at end of file diff --git "a/leetcode/617.\345\220\210\345\271\266\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/617.\345\220\210\345\271\266\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/617.\345\220\210\345\271\266\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/617.\345\220\210\345\271\266\344\272\214\345\217\211\346\240\221.py" index c53162b..de4acf5 100644 --- "a/leetcode/617.\345\220\210\345\271\266\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/617.\345\220\210\345\271\266\344\272\214\345\217\211\346\240\221.py" @@ -1,11 +1,11 @@ -# 方法作用极简化:将两个结点的值求和作为新结点并返回。递归后变成合并两棵树 -class Solution(object): - def mergeTrees(self, t1, t2): - if not t1 and not t2: - return - if not t1 or not t2: - return t1 or t2 - root = TreeNode(t1.val + t2.val) - root.left = self.mergeTrees(t1.left, t2.left) - root.right = self.mergeTrees(t1.right, t2.right) +# 方法作用极简化:将两个结点的值求和作为新结点并返回。递归后变成合并两棵树 +class Solution(object): + def mergeTrees(self, t1, t2): + if not t1 and not t2: + return + if not t1 or not t2: + return t1 or t2 + root = TreeNode(t1.val + t2.val) + root.left = self.mergeTrees(t1.left, t2.left) + root.right = self.mergeTrees(t1.right, t2.right) return root \ No newline at end of file diff --git "a/leetcode/621.\344\273\273\345\212\241\350\260\203\345\272\246\345\231\250.py" "b/leetcode_Python/621.\344\273\273\345\212\241\350\260\203\345\272\246\345\231\250.py" similarity index 98% rename from "leetcode/621.\344\273\273\345\212\241\350\260\203\345\272\246\345\231\250.py" rename to "leetcode_Python/621.\344\273\273\345\212\241\350\260\203\345\272\246\345\231\250.py" index 6e48996..0c4d570 100644 --- "a/leetcode/621.\344\273\273\345\212\241\350\260\203\345\272\246\345\231\250.py" +++ "b/leetcode_Python/621.\344\273\273\345\212\241\350\260\203\345\272\246\345\231\250.py" @@ -1,22 +1,22 @@ -# 完成所有任务的最短时间取决于出现次数最多的任务数量 -# A -> (单位时间) -> (单位时间) -> A -> (单位时间) -> (单位时间) -> A -# 计算过程: (出现最多次数的任务的次数 - 1) * (n + 1) + (出现最多次数的任务个数) -class Solution(object): - def leastInterval(self, tasks, n): - d = {} - # 统计每个任务的次数,并按次数归类存放在字典中 - for task in set(tasks): - count = tasks.count(task) - if count not in d: - d[count] = [task] - else: - d[count] += [task] - # 获取最大次数 - max_count = max(d.keys()) - # 计算最短时间 - res = (max_count - 1) * (n + 1) + len(d[max_count]) - # 当出现次数最多的任务中间的单位时间填满后,仍有其他次数小的任务需要执行 - # 用上面的计算方法会使最短次数比原数组长度短,此时应返回原数组长度 - if res < len(tasks): - return len(tasks) +# 完成所有任务的最短时间取决于出现次数最多的任务数量 +# A -> (单位时间) -> (单位时间) -> A -> (单位时间) -> (单位时间) -> A +# 计算过程: (出现最多次数的任务的次数 - 1) * (n + 1) + (出现最多次数的任务个数) +class Solution(object): + def leastInterval(self, tasks, n): + d = {} + # 统计每个任务的次数,并按次数归类存放在字典中 + for task in set(tasks): + count = tasks.count(task) + if count not in d: + d[count] = [task] + else: + d[count] += [task] + # 获取最大次数 + max_count = max(d.keys()) + # 计算最短时间 + res = (max_count - 1) * (n + 1) + len(d[max_count]) + # 当出现次数最多的任务中间的单位时间填满后,仍有其他次数小的任务需要执行 + # 用上面的计算方法会使最短次数比原数组长度短,此时应返回原数组长度 + if res < len(tasks): + return len(tasks) return res \ No newline at end of file diff --git "a/leetcode/623.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" "b/leetcode_Python/623.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" similarity index 96% rename from "leetcode/623.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" rename to "leetcode_Python/623.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" index 36b6ed1..d78e0f2 100644 --- "a/leetcode/623.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" +++ "b/leetcode_Python/623.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\242\236\345\212\240\344\270\200\350\241\214.py" @@ -1,31 +1,31 @@ -class Solution(object): - def addOneRow(self, root, v, d): - if d == 1: - vnode = TreeNode(v) - vnode.left = root - return vnode - - queue = [(root, 1)] - # 将d-1层的结点添加到queue中 - while queue: - (node, depth) = queue.pop(0) - if depth == d-1: - queue.insert(0, (node, depth)) - break - if node.left: - queue.append((node.left, depth + 1)) - if node.right: - queue.append((node.right, depth + 1)) - # 增加结点 - for (node, depth) in queue: - l = node.left - vnode = TreeNode(v) - node.left = vnode - vnode.left = l - - r = node.right - vnode = TreeNode(v) - node.right = vnode - vnode.right = r - +class Solution(object): + def addOneRow(self, root, v, d): + if d == 1: + vnode = TreeNode(v) + vnode.left = root + return vnode + + queue = [(root, 1)] + # 将d-1层的结点添加到queue中 + while queue: + (node, depth) = queue.pop(0) + if depth == d-1: + queue.insert(0, (node, depth)) + break + if node.left: + queue.append((node.left, depth + 1)) + if node.right: + queue.append((node.right, depth + 1)) + # 增加结点 + for (node, depth) in queue: + l = node.left + vnode = TreeNode(v) + node.left = vnode + vnode.left = l + + r = node.right + vnode = TreeNode(v) + node.right = vnode + vnode.right = r + return root \ No newline at end of file diff --git "a/leetcode/628.\344\270\211\344\270\252\346\225\260\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257.py" "b/leetcode_Python/628.\344\270\211\344\270\252\346\225\260\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257.py" similarity index 97% rename from "leetcode/628.\344\270\211\344\270\252\346\225\260\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257.py" rename to "leetcode_Python/628.\344\270\211\344\270\252\346\225\260\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257.py" index 6e68b8d..a6c69b3 100644 --- "a/leetcode/628.\344\270\211\344\270\252\346\225\260\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257.py" +++ "b/leetcode_Python/628.\344\270\211\344\270\252\346\225\260\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257.py" @@ -1,5 +1,5 @@ -# 两负一正、三正 比大小 -class Solution(object): - def maximumProduct(self, nums): - nums.sort() +# 两负一正、三正 比大小 +class Solution(object): + def maximumProduct(self, nums): + nums.sort() return max(nums[0]*nums[1]*nums[-1], nums[-3]*nums[-2]*nums[-1]) \ No newline at end of file diff --git "a/leetcode/633.\345\271\263\346\226\271\346\225\260\344\271\213\345\222\214.py" "b/leetcode_Python/633.\345\271\263\346\226\271\346\225\260\344\271\213\345\222\214.py" similarity index 97% rename from "leetcode/633.\345\271\263\346\226\271\346\225\260\344\271\213\345\222\214.py" rename to "leetcode_Python/633.\345\271\263\346\226\271\346\225\260\344\271\213\345\222\214.py" index 7939110..da2ef51 100644 --- "a/leetcode/633.\345\271\263\346\226\271\346\225\260\344\271\213\345\222\214.py" +++ "b/leetcode_Python/633.\345\271\263\346\226\271\346\225\260\344\271\213\345\222\214.py" @@ -1,9 +1,9 @@ -# 从0开始遍历判断,如果非负整数c减去一个数的平方后,计算其平方根,结果为整数说明存在 -class Solution(object): - def judgeSquareSum(self, c): - a = 0 - while a**2 <= c: - if int(math.sqrt(c - a**2)) == math.sqrt(c - a**2): - return True - a += 1 +# 从0开始遍历判断,如果非负整数c减去一个数的平方后,计算其平方根,结果为整数说明存在 +class Solution(object): + def judgeSquareSum(self, c): + a = 0 + while a**2 <= c: + if int(math.sqrt(c - a**2)) == math.sqrt(c - a**2): + return True + a += 1 return False \ No newline at end of file diff --git "a/leetcode/637.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\271\263\345\235\207\345\200\274.py" "b/leetcode_Python/637.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\271\263\345\235\207\345\200\274.py" similarity index 97% rename from "leetcode/637.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\271\263\345\235\207\345\200\274.py" rename to "leetcode_Python/637.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\271\263\345\235\207\345\200\274.py" index 11d00d9..b4240b9 100644 --- "a/leetcode/637.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\271\263\345\235\207\345\200\274.py" +++ "b/leetcode_Python/637.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\271\263\345\235\207\345\200\274.py" @@ -1,16 +1,16 @@ -# 获取每层的值后求平均 -class Solution(object): - def averageOfLevels(self, root): - if not root: - return [] - res, cur_level, next_level, cur_val = [], [root], [], [] - while cur_level: - for node in cur_level: - cur_val.append(node.val) - if node.left: - next_level.append(node.left) - if node.right: - next_level.append(node.right) - res.append(float(sum(cur_val))/float(len(cur_val))) - cur_level, next_level, cur_val = next_level, [], [] +# 获取每层的值后求平均 +class Solution(object): + def averageOfLevels(self, root): + if not root: + return [] + res, cur_level, next_level, cur_val = [], [root], [], [] + while cur_level: + for node in cur_level: + cur_val.append(node.val) + if node.left: + next_level.append(node.left) + if node.right: + next_level.append(node.right) + res.append(float(sum(cur_val))/float(len(cur_val))) + cur_level, next_level, cur_val = next_level, [], [] return res \ No newline at end of file diff --git "a/leetcode/643.\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" "b/leetcode_Python/643.\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" similarity index 98% rename from "leetcode/643.\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" rename to "leetcode_Python/643.\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" index 0e6abba..58b692f 100644 --- "a/leetcode/643.\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" +++ "b/leetcode_Python/643.\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.py" @@ -1,8 +1,8 @@ -# 滑动窗口,每次加上后一个数,减去第一个数,获取当前窗口的和再与最大和比较 -class Solution(object): - def findMaxAverage(self, nums, k): - max_sum = cur = sum(nums[:k]) - for i in range(len(nums)-k): - cur += nums[i+k]-nums[i] - max_sum = max(max_sum, cur) +# 滑动窗口,每次加上后一个数,减去第一个数,获取当前窗口的和再与最大和比较 +class Solution(object): + def findMaxAverage(self, nums, k): + max_sum = cur = sum(nums[:k]) + for i in range(len(nums)-k): + cur += nums[i+k]-nums[i] + max_sum = max(max_sum, cur) return max_sum/float(k) \ No newline at end of file diff --git "a/leetcode/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210.py" "b/leetcode_Python/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210.py" similarity index 98% rename from "leetcode/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210.py" rename to "leetcode_Python/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210.py" index d086d9f..093be92 100644 --- "a/leetcode/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210.py" +++ "b/leetcode_Python/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210.py" @@ -1,7 +1,7 @@ -# 获取原数组的总和、去重数组的总和、含重复元素的总和,求差可求得重复元素和缺失元素 -class Solution(object): - def findErrorNums(self, nums): - sum1 = sum([i for i in range(1, len(nums)+1)]) - sum2 = sum(set(nums)) - sum3 = sum(nums) +# 获取原数组的总和、去重数组的总和、含重复元素的总和,求差可求得重复元素和缺失元素 +class Solution(object): + def findErrorNums(self, nums): + sum1 = sum([i for i in range(1, len(nums)+1)]) + sum2 = sum(set(nums)) + sum3 = sum(nums) return [sum3-sum2, sum1-sum2] \ No newline at end of file diff --git "a/leetcode/647.\345\233\236\346\226\207\345\255\220\344\270\262.py" "b/leetcode_Python/647.\345\233\236\346\226\207\345\255\220\344\270\262.py" similarity index 97% rename from "leetcode/647.\345\233\236\346\226\207\345\255\220\344\270\262.py" rename to "leetcode_Python/647.\345\233\236\346\226\207\345\255\220\344\270\262.py" index 0fb55ec..317bedf 100644 --- "a/leetcode/647.\345\233\236\346\226\207\345\255\220\344\270\262.py" +++ "b/leetcode_Python/647.\345\233\236\346\226\207\345\255\220\344\270\262.py" @@ -1,27 +1,27 @@ -# dp[i][j]表示以s[i]开头、s[j]结尾的字符串是否为回文串 -class Solution(object): - def countSubstrings(self, s): - n = len(s) - dp = [[1]*n for _ in range(n)] - for i in range(n-2, -1, -1): - for j in range(i+1, n): - # 当前状态由前一状态和首尾两字符是否相等共同判断 - dp[i][j] = dp[i+1][j-1] and s[i] == s[j] - # 计算二维数组的和并减去下三角的和 - return sum(map(sum, dp)) - (n*(n-1)/2) -# a 0 0 0 1 -# 1 b 0 1 0 -# 1 1 c 0 0 -# 1 1 1 b 0 -# 1 1 1 1 a - - -# 暴力破解,遍历所有子串,是回文串则加1 -class Solution2(object): - def countSubstrings(self, s): - res = 0 - for i in range(len(s)): - for j in range(i+1, len(s)+1): - if s[i:j] == s[i:j][::-1]: - res += 1 - return res +# dp[i][j]表示以s[i]开头、s[j]结尾的字符串是否为回文串 +class Solution(object): + def countSubstrings(self, s): + n = len(s) + dp = [[1]*n for _ in range(n)] + for i in range(n-2, -1, -1): + for j in range(i+1, n): + # 当前状态由前一状态和首尾两字符是否相等共同判断 + dp[i][j] = dp[i+1][j-1] and s[i] == s[j] + # 计算二维数组的和并减去下三角的和 + return sum(map(sum, dp)) - (n*(n-1)/2) +# a 0 0 0 1 +# 1 b 0 1 0 +# 1 1 c 0 0 +# 1 1 1 b 0 +# 1 1 1 1 a + + +# 暴力破解,遍历所有子串,是回文串则加1 +class Solution2(object): + def countSubstrings(self, s): + res = 0 + for i in range(len(s)): + for j in range(i+1, len(s)+1): + if s[i:j] == s[i:j][::-1]: + res += 1 + return res diff --git "a/leetcode/648.\345\215\225\350\257\215\346\233\277\346\215\242.py" "b/leetcode_Python/648.\345\215\225\350\257\215\346\233\277\346\215\242.py" similarity index 97% rename from "leetcode/648.\345\215\225\350\257\215\346\233\277\346\215\242.py" rename to "leetcode_Python/648.\345\215\225\350\257\215\346\233\277\346\215\242.py" index 656eb67..5c7361d 100644 --- "a/leetcode/648.\345\215\225\350\257\215\346\233\277\346\215\242.py" +++ "b/leetcode_Python/648.\345\215\225\350\257\215\346\233\277\346\215\242.py" @@ -1,55 +1,55 @@ -# 暴力法。每个单词对应遍历整个词典,判断是否包含词根,有则替换 -class Solution(object): - def replaceWords(self, dict, sentence): - words = sentence.split(' ') - for i in range(len(words)): - for pre in dict: - # if words[i].startswith(pre): - if pre == words[i][:len(pre)]: - words[i] = pre - return ' '.join(words) - - -# 字典树 -class Solution2(object): - def __init__(self): - self.e = 'end' - self.dtree = {} - - def replaceWords(self, dict, sentence): - self.build_tree(dict) - res = [self.replace(word) for word in sentence.split(' ')] - return ' '.join(res) - - def replace(self, word): - cur = self.dtree - # 遍历单词的每个字符 - for index, char in enumerate(word): - # 若该字符出现在字典树中 - if char in cur: - # 更新当前字典树 - cur = cur[char] - # 判断前缀是否结束 - if self.e in cur: - return word[:index+1] - # 若无,则直接返回该单词 - else: - return word - # 单词遍历完,前缀未结束,直接返回该单词 - return word - - # {'b': {'a': {'t': {'end': ''}}}, 'r': {'a': {'t': {'end': ''}}}, 'c': {'a': {'t': {'end': ''}}}} - def build_tree(self, dict): - # 遍历每个词根 - for pre in dict: - # 直接赋值引用,同步更新 - cur = self.dtree - # 遍历词根的每个字符 - for char in pre: - # 如果该字符不在当前字典中,则当前字符键的值设为空字典 - if char not in cur: - cur[char] = {} - # 当前字典更新为此字符键的值字典 - cur = cur[char] - # 字符遍历完成在尾部添加结束标志 +# 暴力法。每个单词对应遍历整个词典,判断是否包含词根,有则替换 +class Solution(object): + def replaceWords(self, dict, sentence): + words = sentence.split(' ') + for i in range(len(words)): + for pre in dict: + # if words[i].startswith(pre): + if pre == words[i][:len(pre)]: + words[i] = pre + return ' '.join(words) + + +# 字典树 +class Solution2(object): + def __init__(self): + self.e = 'end' + self.dtree = {} + + def replaceWords(self, dict, sentence): + self.build_tree(dict) + res = [self.replace(word) for word in sentence.split(' ')] + return ' '.join(res) + + def replace(self, word): + cur = self.dtree + # 遍历单词的每个字符 + for index, char in enumerate(word): + # 若该字符出现在字典树中 + if char in cur: + # 更新当前字典树 + cur = cur[char] + # 判断前缀是否结束 + if self.e in cur: + return word[:index+1] + # 若无,则直接返回该单词 + else: + return word + # 单词遍历完,前缀未结束,直接返回该单词 + return word + + # {'b': {'a': {'t': {'end': ''}}}, 'r': {'a': {'t': {'end': ''}}}, 'c': {'a': {'t': {'end': ''}}}} + def build_tree(self, dict): + # 遍历每个词根 + for pre in dict: + # 直接赋值引用,同步更新 + cur = self.dtree + # 遍历词根的每个字符 + for char in pre: + # 如果该字符不在当前字典中,则当前字符键的值设为空字典 + if char not in cur: + cur[char] = {} + # 当前字典更新为此字符键的值字典 + cur = cur[char] + # 字符遍历完成在尾部添加结束标志 cur[self.e] = '' \ No newline at end of file diff --git "a/leetcode/652.\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" "b/leetcode_Python/652.\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" similarity index 97% rename from "leetcode/652.\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" rename to "leetcode_Python/652.\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" index 7d32e89..0ca5a34 100644 --- "a/leetcode/652.\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" +++ "b/leetcode_Python/652.\345\257\273\346\211\276\351\207\215\345\244\215\347\232\204\345\255\220\346\240\221.py" @@ -1,18 +1,18 @@ -# 用字典存放序列化的子树,遍历过程若字典出现重复的序列化字符串,则将该子树添加到数组 -class Solution(object): - def findDuplicateSubtrees(self, root): - global res, d - res = [] - # value默认为0 - d = collections.defaultdict(int) - self.findtree(root) - return res - - def findtree(self, root): - if not root: - return '#' - sontree = str(root.val) + ',' + self.findtree(root.left) + ',' + self.findtree(root.right) - if d[sontree] == 1: - res.append(root) - d[sontree] += 1 +# 用字典存放序列化的子树,遍历过程若字典出现重复的序列化字符串,则将该子树添加到数组 +class Solution(object): + def findDuplicateSubtrees(self, root): + global res, d + res = [] + # value默认为0 + d = collections.defaultdict(int) + self.findtree(root) + return res + + def findtree(self, root): + if not root: + return '#' + sontree = str(root.val) + ',' + self.findtree(root.left) + ',' + self.findtree(root.right) + if d[sontree] == 1: + res.append(root) + d[sontree] += 1 return sontree \ No newline at end of file diff --git "a/leetcode/653.\344\270\244\346\225\260\344\271\213\345\222\214IV-\350\276\223\345\205\245BST.py" "b/leetcode_Python/653.\344\270\244\346\225\260\344\271\213\345\222\214IV-\350\276\223\345\205\245BST.py" similarity index 97% rename from "leetcode/653.\344\270\244\346\225\260\344\271\213\345\222\214IV-\350\276\223\345\205\245BST.py" rename to "leetcode_Python/653.\344\270\244\346\225\260\344\271\213\345\222\214IV-\350\276\223\345\205\245BST.py" index 672a94f..81092f4 100644 --- "a/leetcode/653.\344\270\244\346\225\260\344\271\213\345\222\214IV-\350\276\223\345\205\245BST.py" +++ "b/leetcode_Python/653.\344\270\244\346\225\260\344\271\213\345\222\214IV-\350\276\223\345\205\245BST.py" @@ -1,14 +1,14 @@ -# 中序遍历得到结点值数组,再判断是否包含两数之和等于目标结果 -class Solution(object): - def findTarget(self, root, k): - self.res = [] - def inorder(root): - if root: - inorder(root.left) - self.res.append(root.val) - inorder(root.right) - inorder(root) - for i,v in enumerate(self.res): - if k-v in self.res[i+1:]: - return True +# 中序遍历得到结点值数组,再判断是否包含两数之和等于目标结果 +class Solution(object): + def findTarget(self, root, k): + self.res = [] + def inorder(root): + if root: + inorder(root.left) + self.res.append(root.val) + inorder(root.right) + inorder(root) + for i,v in enumerate(self.res): + if k-v in self.res[i+1:]: + return True return False \ No newline at end of file diff --git "a/leetcode/654.\346\234\200\345\244\247\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/654.\346\234\200\345\244\247\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/654.\346\234\200\345\244\247\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/654.\346\234\200\345\244\247\344\272\214\345\217\211\346\240\221.py" index 6d4968c..d72e266 100644 --- "a/leetcode/654.\346\234\200\345\244\247\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/654.\346\234\200\345\244\247\344\272\214\345\217\211\346\240\221.py" @@ -1,18 +1,18 @@ -class Solution(object): - def constructMaximumBinaryTree(self, nums): - root = TreeNode(max(nums)) - index = nums.index(max(nums)) - if index > 0: - root.left = self.constructMaximumBinaryTree(nums[:index]) - if index < len(nums)-1: - root.right = self.constructMaximumBinaryTree(nums[index+1:]) - return root - -################### 递归思路 #################### -# 方法作用极简化:判断一个结点的情况 -# 方法作用描述:参数给一个数组,取该数组的最大值作为结点,并返回该结点 -# 递归:根的左右孩子都需要剩余数组里的最大值作为结点,使用递归 -class Solution(object): - def constructMaximumBinaryTree(self, nums): - root = TreeNode(max(nums)) +class Solution(object): + def constructMaximumBinaryTree(self, nums): + root = TreeNode(max(nums)) + index = nums.index(max(nums)) + if index > 0: + root.left = self.constructMaximumBinaryTree(nums[:index]) + if index < len(nums)-1: + root.right = self.constructMaximumBinaryTree(nums[index+1:]) + return root + +################### 递归思路 #################### +# 方法作用极简化:判断一个结点的情况 +# 方法作用描述:参数给一个数组,取该数组的最大值作为结点,并返回该结点 +# 递归:根的左右孩子都需要剩余数组里的最大值作为结点,使用递归 +class Solution(object): + def constructMaximumBinaryTree(self, nums): + root = TreeNode(max(nums)) return root \ No newline at end of file diff --git "a/leetcode/655.\350\276\223\345\207\272\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/655.\350\276\223\345\207\272\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/655.\350\276\223\345\207\272\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/655.\350\276\223\345\207\272\344\272\214\345\217\211\346\240\221.py" index 2a0d3e7..f994026 100644 --- "a/leetcode/655.\350\276\223\345\207\272\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/655.\350\276\223\345\207\272\344\272\214\345\217\211\346\240\221.py" @@ -1,22 +1,22 @@ -class Solution(object): - def printTree(self, root): - - # 求树的深度 - def high(root): - if not root: - return 0 - return 1 + max(high(root.left), high(root.right)) - - # 得到数组的大小 - height, width = high(root), 2**high(root)-1 - res = [['' for j in range(width)] for i in range(height)] - - # 判断每个结点的位置 - def locat(res, root, h, w): - if root: - res[h-1][w] = str(root.val) - locat(res, root.left, h+1, w-2**(height-h-1)) - locat(res, root.right, h+1, w+2**(height-h-1)) - - locat(res, root, 1, width/2) +class Solution(object): + def printTree(self, root): + + # 求树的深度 + def high(root): + if not root: + return 0 + return 1 + max(high(root.left), high(root.right)) + + # 得到数组的大小 + height, width = high(root), 2**high(root)-1 + res = [['' for j in range(width)] for i in range(height)] + + # 判断每个结点的位置 + def locat(res, root, h, w): + if root: + res[h-1][w] = str(root.val) + locat(res, root.left, h+1, w-2**(height-h-1)) + locat(res, root.right, h+1, w+2**(height-h-1)) + + locat(res, root, 1, width/2) return res \ No newline at end of file diff --git "a/leetcode/657.\346\234\272\345\231\250\344\272\272\350\203\275\345\220\246\350\277\224\345\233\236\345\216\237\347\202\271.py" "b/leetcode_Python/657.\346\234\272\345\231\250\344\272\272\350\203\275\345\220\246\350\277\224\345\233\236\345\216\237\347\202\271.py" similarity index 96% rename from "leetcode/657.\346\234\272\345\231\250\344\272\272\350\203\275\345\220\246\350\277\224\345\233\236\345\216\237\347\202\271.py" rename to "leetcode_Python/657.\346\234\272\345\231\250\344\272\272\350\203\275\345\220\246\350\277\224\345\233\236\345\216\237\347\202\271.py" index dab32e3..ecad32d 100644 --- "a/leetcode/657.\346\234\272\345\231\250\344\272\272\350\203\275\345\220\246\350\277\224\345\233\236\345\216\237\347\202\271.py" +++ "b/leetcode_Python/657.\346\234\272\345\231\250\344\272\272\350\203\275\345\220\246\350\277\224\345\233\236\345\216\237\347\202\271.py" @@ -1,21 +1,21 @@ -# 方法一:横轴、纵轴方向记录移动位置 -class Solution(object): - def judgeCircle(self, moves): - x = y = 0 - for i in moves: - if i == 'L': - x -= 1 - elif i == 'R': - x += 1 - elif i == 'U': - y += 1 - else: - y -= 1 - if x==0 and y==0: - return True - return False - -# 方法二:统计左与右、上与下的个数是否相等 -class Solution(object): - def judgeCircle(self, moves): +# 方法一:横轴、纵轴方向记录移动位置 +class Solution(object): + def judgeCircle(self, moves): + x = y = 0 + for i in moves: + if i == 'L': + x -= 1 + elif i == 'R': + x += 1 + elif i == 'U': + y += 1 + else: + y -= 1 + if x==0 and y==0: + return True + return False + +# 方法二:统计左与右、上与下的个数是否相等 +class Solution(object): + def judgeCircle(self, moves): return moves.count('L') == moves.count('R') and moves.count('U') == moves.count('D') \ No newline at end of file diff --git "a/leetcode/661.\345\233\276\347\211\207\345\271\263\346\273\221\345\231\250.py" "b/leetcode_Python/661.\345\233\276\347\211\207\345\271\263\346\273\221\345\231\250.py" similarity index 97% rename from "leetcode/661.\345\233\276\347\211\207\345\271\263\346\273\221\345\231\250.py" rename to "leetcode_Python/661.\345\233\276\347\211\207\345\271\263\346\273\221\345\231\250.py" index 873744e..04feb41 100644 --- "a/leetcode/661.\345\233\276\347\211\207\345\271\263\346\273\221\345\231\250.py" +++ "b/leetcode_Python/661.\345\233\276\347\211\207\345\271\263\346\273\221\345\231\250.py" @@ -1,19 +1,19 @@ -# 遍历每个元素,将其周围的元素累加取平均,然后添加到该行的新数组中,一行遍历完成后将改行结果添加到矩阵数组中 -class Solution(object): - def imageSmoother(self, M): - dx = [0, 0, 1, 1, 1, -1, -1, -1] - dy = [1, -1, 1, 0, -1, 1, 0, -1] - res = [] - row, col = len(M), len(M[0]) - for i in range(row): - cur = [] - for j in range(col): - sum = M[i][j] - count = 1 - for x, y in zip(dx, dy): - if 0 <= i+x < row and 0 <= j+y < col : - sum += M[i+x][j+y] - count += 1 - cur.append(sum/count) - res.append(cur) +# 遍历每个元素,将其周围的元素累加取平均,然后添加到该行的新数组中,一行遍历完成后将改行结果添加到矩阵数组中 +class Solution(object): + def imageSmoother(self, M): + dx = [0, 0, 1, 1, 1, -1, -1, -1] + dy = [1, -1, 1, 0, -1, 1, 0, -1] + res = [] + row, col = len(M), len(M[0]) + for i in range(row): + cur = [] + for j in range(col): + sum = M[i][j] + count = 1 + for x, y in zip(dx, dy): + if 0 <= i+x < row and 0 <= j+y < col : + sum += M[i+x][j+y] + count += 1 + cur.append(sum/count) + res.append(cur) return res \ No newline at end of file diff --git "a/leetcode/662.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\345\256\275\345\272\246.py" "b/leetcode_Python/662.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\345\256\275\345\272\246.py" similarity index 97% rename from "leetcode/662.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\345\256\275\345\272\246.py" rename to "leetcode_Python/662.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\345\256\275\345\272\246.py" index d830d85..de2bc2f 100644 --- "a/leetcode/662.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\345\256\275\345\272\246.py" +++ "b/leetcode_Python/662.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\345\256\275\345\272\246.py" @@ -1,17 +1,17 @@ -class Solution(object): - def widthOfBinaryTree(self, root): - # 结点与对应满二叉树的位置 - q = [(root, 1)] - res = 0 - while q: - # 每层最后一个结点的位置减去第一个结点的位置再加1得到宽度 - width = q[-1][1] - q[0][1] + 1 - res = max(width, res) - # 弹出当前层结点,添加下一层结点 - for _ in range(len(q)): - n, c = q.pop(0) - if n.left: - q.append((n.left, c*2)) - if n.right: - q.append((n.right, c*2+1)) +class Solution(object): + def widthOfBinaryTree(self, root): + # 结点与对应满二叉树的位置 + q = [(root, 1)] + res = 0 + while q: + # 每层最后一个结点的位置减去第一个结点的位置再加1得到宽度 + width = q[-1][1] - q[0][1] + 1 + res = max(width, res) + # 弹出当前层结点,添加下一层结点 + for _ in range(len(q)): + n, c = q.pop(0) + if n.left: + q.append((n.left, c*2)) + if n.right: + q.append((n.right, c*2+1)) return res \ No newline at end of file diff --git "a/leetcode/665.\351\235\236\351\200\222\345\207\217\346\225\260\345\210\227.py" "b/leetcode_Python/665.\351\235\236\351\200\222\345\207\217\346\225\260\345\210\227.py" similarity index 97% rename from "leetcode/665.\351\235\236\351\200\222\345\207\217\346\225\260\345\210\227.py" rename to "leetcode_Python/665.\351\235\236\351\200\222\345\207\217\346\225\260\345\210\227.py" index bbbb73d..fe34001 100644 --- "a/leetcode/665.\351\235\236\351\200\222\345\207\217\346\225\260\345\210\227.py" +++ "b/leetcode_Python/665.\351\235\236\351\200\222\345\207\217\346\225\260\345\210\227.py" @@ -1,18 +1,18 @@ -class Solution(object): - def checkPossibility(self, nums): - if len(nums) < 3: - return True - count = 0 - for i in range(1, len(nums)): - if nums[i] < nums[i-1]: - count += 1 - if count > 1: - return False - # 发现不满足条件的值要先改动,后面再继续判断 - # 2 4 2(i) 6 改i-1可使后面尽可能满足递增 - if i-2 < 0 or nums[i-2] <= nums[i]: - nums[i-1] = nums[i] - # 3 4 2(i) 6 i-1不能改,只能改当前值 - else: - nums[i] = nums[i-1] +class Solution(object): + def checkPossibility(self, nums): + if len(nums) < 3: + return True + count = 0 + for i in range(1, len(nums)): + if nums[i] < nums[i-1]: + count += 1 + if count > 1: + return False + # 发现不满足条件的值要先改动,后面再继续判断 + # 2 4 2(i) 6 改i-1可使后面尽可能满足递增 + if i-2 < 0 or nums[i-2] <= nums[i]: + nums[i-1] = nums[i] + # 3 4 2(i) 6 i-1不能改,只能改当前值 + else: + nums[i] = nums[i-1] return True \ No newline at end of file diff --git "a/leetcode/669.\344\277\256\345\211\252\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" "b/leetcode_Python/669.\344\277\256\345\211\252\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" similarity index 98% rename from "leetcode/669.\344\277\256\345\211\252\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" rename to "leetcode_Python/669.\344\277\256\345\211\252\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" index afa25b6..51b6aef 100644 --- "a/leetcode/669.\344\277\256\345\211\252\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" +++ "b/leetcode_Python/669.\344\277\256\345\211\252\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221.py" @@ -1,15 +1,15 @@ -# 从根节点开始,若根节点在给定范围左侧,那么他和他的左子树完全裁剪; -# 若根节点在给定范围右侧,那么他和他的右子树完全裁剪; -# 若根节点在给定范围内,不用裁剪,按照递归分别推出他左右子树的裁剪结果。 -class Solution(object): - def trimBST(self, root, L, R): - if not root: - return - elif root.val < L: - return self.trimBST(root.right, L, R) - elif root.val > R: - return self.trimBST(root.left, L, R) - else: - root.left = self.trimBST(root.left, L, R) - root.right = self.trimBST(root.right, L, R) +# 从根节点开始,若根节点在给定范围左侧,那么他和他的左子树完全裁剪; +# 若根节点在给定范围右侧,那么他和他的右子树完全裁剪; +# 若根节点在给定范围内,不用裁剪,按照递归分别推出他左右子树的裁剪结果。 +class Solution(object): + def trimBST(self, root, L, R): + if not root: + return + elif root.val < L: + return self.trimBST(root.right, L, R) + elif root.val > R: + return self.trimBST(root.left, L, R) + else: + root.left = self.trimBST(root.left, L, R) + root.right = self.trimBST(root.right, L, R) return root \ No newline at end of file diff --git "a/leetcode/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271.py" "b/leetcode_Python/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271.py" similarity index 97% rename from "leetcode/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271.py" rename to "leetcode_Python/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271.py" index c13c54e..52c425c 100644 --- "a/leetcode/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271.py" +++ "b/leetcode_Python/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271.py" @@ -1,15 +1,15 @@ -# 由题可知,根结点是最小的结点,则左右子树中节点值不等于根节点值的所有节点中,值最小的即为第二小的值 -class Solution(object): - def findSecondMinimumValue(self, root): - if not root or not root.left: - return -1 - return self.find(root, root.val) - - def find(self, root, minVal): - if not root.left: - return -1 if root.val == minVal else root.val - leftMin = self.find(root.left, minVal) - rightMin = self.find(root.right, minVal) - if leftMin == -1 or rightMin == -1: - return max(leftMin, rightMin) +# 由题可知,根结点是最小的结点,则左右子树中节点值不等于根节点值的所有节点中,值最小的即为第二小的值 +class Solution(object): + def findSecondMinimumValue(self, root): + if not root or not root.left: + return -1 + return self.find(root, root.val) + + def find(self, root, minVal): + if not root.left: + return -1 if root.val == minVal else root.val + leftMin = self.find(root.left, minVal) + rightMin = self.find(root.right, minVal) + if leftMin == -1 or rightMin == -1: + return max(leftMin, rightMin) return min(leftMin, rightMin) \ No newline at end of file diff --git "a/leetcode/674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" "b/leetcode_Python/674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" similarity index 97% rename from "leetcode/674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" rename to "leetcode_Python/674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" index 4f10ffb..7fbc3a6 100644 --- "a/leetcode/674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" +++ "b/leetcode_Python/674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.py" @@ -1,13 +1,13 @@ -# 遍历数组,如果元素递增,则次数加1,并更新最大次数。如果非递增,则次数重置1 -class Solution(object): - def findLengthOfLCIS(self, nums): - if not nums: - return 0 - res = count = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i-1]: - count += 1 - res = max(res, count) - else: - count = 1 +# 遍历数组,如果元素递增,则次数加1,并更新最大次数。如果非递增,则次数重置1 +class Solution(object): + def findLengthOfLCIS(self, nums): + if not nums: + return 0 + res = count = 1 + for i in range(1, len(nums)): + if nums[i] > nums[i-1]: + count += 1 + res = max(res, count) + else: + count = 1 return res \ No newline at end of file diff --git "a/leetcode/676.\345\256\236\347\216\260\344\270\200\344\270\252\351\255\224\346\263\225\345\255\227\345\205\270.py" "b/leetcode_Python/676.\345\256\236\347\216\260\344\270\200\344\270\252\351\255\224\346\263\225\345\255\227\345\205\270.py" similarity index 96% rename from "leetcode/676.\345\256\236\347\216\260\344\270\200\344\270\252\351\255\224\346\263\225\345\255\227\345\205\270.py" rename to "leetcode_Python/676.\345\256\236\347\216\260\344\270\200\344\270\252\351\255\224\346\263\225\345\255\227\345\205\270.py" index 296b91d..a240261 100644 --- "a/leetcode/676.\345\256\236\347\216\260\344\270\200\344\270\252\351\255\224\346\263\225\345\255\227\345\205\270.py" +++ "b/leetcode_Python/676.\345\256\236\347\216\260\344\270\200\344\270\252\351\255\224\346\263\225\345\255\227\345\205\270.py" @@ -1,20 +1,20 @@ -class MagicDictionary(object): - - def __init__(self): - self.d = [] - - def buildDict(self, dict): - self.d = dict - - # 列表元素比较,长度相同且仅一个字符不同则返回True - def search(self, word): - n = len(word) - for key in self.d: - if len(key) == n: - count = 0 - for i in range(n): - if key[i] != word[i]: - count += 1 - if count == 1: - return True +class MagicDictionary(object): + + def __init__(self): + self.d = [] + + def buildDict(self, dict): + self.d = dict + + # 列表元素比较,长度相同且仅一个字符不同则返回True + def search(self, word): + n = len(word) + for key in self.d: + if len(key) == n: + count = 0 + for i in range(n): + if key[i] != word[i]: + count += 1 + if count == 1: + return True return False \ No newline at end of file diff --git "a/leetcode/677.\351\224\256\345\200\274\346\230\240\345\260\204.py" "b/leetcode_Python/677.\351\224\256\345\200\274\346\230\240\345\260\204.py" similarity index 96% rename from "leetcode/677.\351\224\256\345\200\274\346\230\240\345\260\204.py" rename to "leetcode_Python/677.\351\224\256\345\200\274\346\230\240\345\260\204.py" index dba229c..59d19de 100644 --- "a/leetcode/677.\351\224\256\345\200\274\346\230\240\345\260\204.py" +++ "b/leetcode_Python/677.\351\224\256\345\200\274\346\230\240\345\260\204.py" @@ -1,57 +1,57 @@ -# 字典树 -class MapSum(object): - - def __init__(self): - self.root = {} - - def insert(self, key, val): - # 直接赋值引用,同步更新 - node = self.root - # 遍历单词每个字符,逐层向内扩展当前字典树 - for char in key: - node = node.setdefault(char, {}) - # 结尾添加结束标志 - node['end'] = val - - def sum(self, prefix): - node = self.root - # 遍历前缀每个字符,逐层向内更新,得到该前缀下的字典树 - for char in prefix: - node = node.setdefault(char, {}) - - self.res = 0 - - # 递归遍历得到当前字典树所有值 - def dfs(node): - for key, val in node.items(): - if key == 'end': - self.res += val - else: - dfs(val) - - dfs(node) - return self.res - - -# 普通字典 -class MapSum2(object): - - def __init__(self): - self.d = {} - - def insert(self, key, val): - self.d[key] = val - - def sum(self, prefix): - res = 0 - for key in self.d: - if prefix == key[:len(prefix)]: - res += self.d[key] - return res - - # def sum(self, prefix): - # res = 0 - # for key, val in self.d.items(): - # if key.startswith(prefix): - # res += val +# 字典树 +class MapSum(object): + + def __init__(self): + self.root = {} + + def insert(self, key, val): + # 直接赋值引用,同步更新 + node = self.root + # 遍历单词每个字符,逐层向内扩展当前字典树 + for char in key: + node = node.setdefault(char, {}) + # 结尾添加结束标志 + node['end'] = val + + def sum(self, prefix): + node = self.root + # 遍历前缀每个字符,逐层向内更新,得到该前缀下的字典树 + for char in prefix: + node = node.setdefault(char, {}) + + self.res = 0 + + # 递归遍历得到当前字典树所有值 + def dfs(node): + for key, val in node.items(): + if key == 'end': + self.res += val + else: + dfs(val) + + dfs(node) + return self.res + + +# 普通字典 +class MapSum2(object): + + def __init__(self): + self.d = {} + + def insert(self, key, val): + self.d[key] = val + + def sum(self, prefix): + res = 0 + for key in self.d: + if prefix == key[:len(prefix)]: + res += self.d[key] + return res + + # def sum(self, prefix): + # res = 0 + # for key, val in self.d.items(): + # if key.startswith(prefix): + # res += val # return res \ No newline at end of file diff --git "a/leetcode/680.\351\252\214\350\257\201\345\233\236\346\226\207\345\255\227\347\254\246\344\270\262II.py" "b/leetcode_Python/680.\351\252\214\350\257\201\345\233\236\346\226\207\345\255\227\347\254\246\344\270\262II.py" similarity index 96% rename from "leetcode/680.\351\252\214\350\257\201\345\233\236\346\226\207\345\255\227\347\254\246\344\270\262II.py" rename to "leetcode_Python/680.\351\252\214\350\257\201\345\233\236\346\226\207\345\255\227\347\254\246\344\270\262II.py" index 52e3c89..40cd997 100644 --- "a/leetcode/680.\351\252\214\350\257\201\345\233\236\346\226\207\345\255\227\347\254\246\344\270\262II.py" +++ "b/leetcode_Python/680.\351\252\214\350\257\201\345\233\236\346\226\207\345\255\227\347\254\246\344\270\262II.py" @@ -1,27 +1,27 @@ -# 方法一:利用反转字符串比较 -class Solution(object): - def validPalindrome(self, s): - n = len(s) - if n < 3: - return True - - s2 = s[::-1] - i = 0 - while i < len(s) and s[i] == s2[i]: - i += 1 - return s[i:n-1-i] == s2[i+1:n-i] or s[i+1:n-i] == s2[i:n-1-i] - -# 方法二:在原字符串上比较 -class Solution(object): - def validPalindrome(self, s): - n = len(s) - if n < 3: - return True - - l, r = 0, n-1 - while l < r and s[l] == s[r]: - l += 1 - r -= 1 - if l >= r: - return True +# 方法一:利用反转字符串比较 +class Solution(object): + def validPalindrome(self, s): + n = len(s) + if n < 3: + return True + + s2 = s[::-1] + i = 0 + while i < len(s) and s[i] == s2[i]: + i += 1 + return s[i:n-1-i] == s2[i+1:n-i] or s[i+1:n-i] == s2[i:n-1-i] + +# 方法二:在原字符串上比较 +class Solution(object): + def validPalindrome(self, s): + n = len(s) + if n < 3: + return True + + l, r = 0, n-1 + while l < r and s[l] == s[r]: + l += 1 + r -= 1 + if l >= r: + return True return s[l+1:r+1] == s[l+1:r+1][::-1] or s[l:r] == s[l:r][::-1] \ No newline at end of file diff --git "a/leetcode/682.\346\243\222\347\220\203\346\257\224\350\265\233.py" "b/leetcode_Python/682.\346\243\222\347\220\203\346\257\224\350\265\233.py" similarity index 97% rename from "leetcode/682.\346\243\222\347\220\203\346\257\224\350\265\233.py" rename to "leetcode_Python/682.\346\243\222\347\220\203\346\257\224\350\265\233.py" index 698069e..bbfc903 100644 --- "a/leetcode/682.\346\243\222\347\220\203\346\257\224\350\265\233.py" +++ "b/leetcode_Python/682.\346\243\222\347\220\203\346\257\224\350\265\233.py" @@ -1,14 +1,14 @@ -# 用数组添加、删除数据即可,最后求和 -class Solution(object): - def calPoints(self, ops): - res = [] - for op in ops: - if op == '+': - res.append(res[-1] + res[-2]) - elif op == 'D': - res.append(res[-1] * 2) - elif op == 'C': - res.remove(res[-1]) - else: - res.append(int(op)) +# 用数组添加、删除数据即可,最后求和 +class Solution(object): + def calPoints(self, ops): + res = [] + for op in ops: + if op == '+': + res.append(res[-1] + res[-2]) + elif op == 'D': + res.append(res[-1] * 2) + elif op == 'C': + res.remove(res[-1]) + else: + res.append(int(op)) return sum(res) \ No newline at end of file diff --git "a/leetcode/684.\345\206\227\344\275\231\350\277\236\346\216\245.py" "b/leetcode_Python/684.\345\206\227\344\275\231\350\277\236\346\216\245.py" similarity index 97% rename from "leetcode/684.\345\206\227\344\275\231\350\277\236\346\216\245.py" rename to "leetcode_Python/684.\345\206\227\344\275\231\350\277\236\346\216\245.py" index b75f6cd..957b376 100644 --- "a/leetcode/684.\345\206\227\344\275\231\350\277\236\346\216\245.py" +++ "b/leetcode_Python/684.\345\206\227\344\275\231\350\277\236\346\216\245.py" @@ -1,18 +1,18 @@ -# 寻根,当一条边让数组内构成循环,则删除该边 -class Solution(object): - def findRedundantConnection(self, edges): - tree = [-1] * (len(edges) + 1) - for edge in edges: - a = self.findRoot(edge[0], tree) - b = self.findRoot(edge[1], tree) - if a != b: - tree[a] = b - else: - return edge - - def findRoot(self, x, tree): - if tree[x] == -1: - return x - root = self.findRoot(tree[x], tree) - tree[x] = root +# 寻根,当一条边让数组内构成循环,则删除该边 +class Solution(object): + def findRedundantConnection(self, edges): + tree = [-1] * (len(edges) + 1) + for edge in edges: + a = self.findRoot(edge[0], tree) + b = self.findRoot(edge[1], tree) + if a != b: + tree[a] = b + else: + return edge + + def findRoot(self, x, tree): + if tree[x] == -1: + return x + root = self.findRoot(tree[x], tree) + tree[x] = root return root \ No newline at end of file diff --git "a/leetcode/685.\345\206\227\344\275\231\350\277\236\346\216\245II.py" "b/leetcode_Python/685.\345\206\227\344\275\231\350\277\236\346\216\245II.py" similarity index 97% rename from "leetcode/685.\345\206\227\344\275\231\350\277\236\346\216\245II.py" rename to "leetcode_Python/685.\345\206\227\344\275\231\350\277\236\346\216\245II.py" index 4f2707e..9b0fbcf 100644 --- "a/leetcode/685.\345\206\227\344\275\231\350\277\236\346\216\245II.py" +++ "b/leetcode_Python/685.\345\206\227\344\275\231\350\277\236\346\216\245II.py" @@ -1,33 +1,33 @@ -class Solution(object): - def findRedundantDirectedConnection(self, edges): - def find(x, tree): - if tree[x] == -1: - return x - root = find(tree[x], tree) - tree[x] = root - return root - - # 用 count 来计数不合法的边 - count = 0 - res = [] - tree = [-1] * (len(edges)+1) - # 第一轮查找不合法的边(正序) - for parent, child in edges: - # child已经有parent 或 child的parent的parent(或者一直往上找)就是 child 本身 - if tree[child] != -1 or find(parent, tree) == child: - res = [parent, child] - count += 1 - else: - tree[child] = parent - # 如果只有一条不合法的边,直接返回 - if count == 1: - return res - - # 要求返回最后一条边,重置 tree 并开始第二轮查找(逆序) - tree = [-1] * (len(edges)+1) - for parent, child in edges[::-1]: - if tree[child] != -1 or find(parent, tree) == child: - return [parent, child] - else: - tree[child] = parent +class Solution(object): + def findRedundantDirectedConnection(self, edges): + def find(x, tree): + if tree[x] == -1: + return x + root = find(tree[x], tree) + tree[x] = root + return root + + # 用 count 来计数不合法的边 + count = 0 + res = [] + tree = [-1] * (len(edges)+1) + # 第一轮查找不合法的边(正序) + for parent, child in edges: + # child已经有parent 或 child的parent的parent(或者一直往上找)就是 child 本身 + if tree[child] != -1 or find(parent, tree) == child: + res = [parent, child] + count += 1 + else: + tree[child] = parent + # 如果只有一条不合法的边,直接返回 + if count == 1: + return res + + # 要求返回最后一条边,重置 tree 并开始第二轮查找(逆序) + tree = [-1] * (len(edges)+1) + for parent, child in edges[::-1]: + if tree[child] != -1 or find(parent, tree) == child: + return [parent, child] + else: + tree[child] = parent return res \ No newline at end of file diff --git "a/leetcode/686.\351\207\215\345\244\215\345\217\240\345\212\240\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" "b/leetcode_Python/686.\351\207\215\345\244\215\345\217\240\345\212\240\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" similarity index 96% rename from "leetcode/686.\351\207\215\345\244\215\345\217\240\345\212\240\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" rename to "leetcode_Python/686.\351\207\215\345\244\215\345\217\240\345\212\240\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" index 3132b29..b4ce530 100644 --- "a/leetcode/686.\351\207\215\345\244\215\345\217\240\345\212\240\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" +++ "b/leetcode_Python/686.\351\207\215\345\244\215\345\217\240\345\212\240\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" @@ -1,14 +1,14 @@ -class Solution(object): - def repeatedStringMatch(self, A, B): - count = 1 - S = A - while len(S) < len(B): - S += A - count += 1 - # 判断第一次叠加后长度大于B是否包含 - if B in S: - return count - # 判断第二次,如果不包含则不存在 - if B in S+A: - return count+1 +class Solution(object): + def repeatedStringMatch(self, A, B): + count = 1 + S = A + while len(S) < len(B): + S += A + count += 1 + # 判断第一次叠加后长度大于B是否包含 + if B in S: + return count + # 判断第二次,如果不包含则不存在 + if B in S+A: + return count+1 return -1 \ No newline at end of file diff --git "a/leetcode/687.\346\234\200\351\225\277\345\220\214\345\200\274\350\267\257\345\276\204.py" "b/leetcode_Python/687.\346\234\200\351\225\277\345\220\214\345\200\274\350\267\257\345\276\204.py" similarity index 96% rename from "leetcode/687.\346\234\200\351\225\277\345\220\214\345\200\274\350\267\257\345\276\204.py" rename to "leetcode_Python/687.\346\234\200\351\225\277\345\220\214\345\200\274\350\267\257\345\276\204.py" index bfc1447..8e08b0f 100644 --- "a/leetcode/687.\346\234\200\351\225\277\345\220\214\345\200\274\350\267\257\345\276\204.py" +++ "b/leetcode_Python/687.\346\234\200\351\225\277\345\220\214\345\200\274\350\267\257\345\276\204.py" @@ -1,21 +1,21 @@ -class Solution(object): - - def __init__(self): - self.maxLen = 0 - - def longestUnivaluePath(self, root): - if not root: - return 0 - self.getMaxLen(root, root.val) - return self.maxLen - - # 由左右最长同值路径相加 - def getMaxLen(self, root, val): - if not root: - return 0 - left = self.getMaxLen(root.left, root.val) - right = self.getMaxLen(root.right, root.val) - self.maxLen = max(self.maxLen, left + right) - if root.val == val: - return max(left, right) + 1 +class Solution(object): + + def __init__(self): + self.maxLen = 0 + + def longestUnivaluePath(self, root): + if not root: + return 0 + self.getMaxLen(root, root.val) + return self.maxLen + + # 由左右最长同值路径相加 + def getMaxLen(self, root, val): + if not root: + return 0 + left = self.getMaxLen(root.left, root.val) + right = self.getMaxLen(root.right, root.val) + self.maxLen = max(self.maxLen, left + right) + if root.val == val: + return max(left, right) + 1 return 0 \ No newline at end of file diff --git "a/leetcode/690.\345\221\230\345\267\245\347\232\204\351\207\215\350\246\201\346\200\247.py" "b/leetcode_Python/690.\345\221\230\345\267\245\347\232\204\351\207\215\350\246\201\346\200\247.py" similarity index 97% rename from "leetcode/690.\345\221\230\345\267\245\347\232\204\351\207\215\350\246\201\346\200\247.py" rename to "leetcode_Python/690.\345\221\230\345\267\245\347\232\204\351\207\215\350\246\201\346\200\247.py" index a405bdf..d0154d3 100644 --- "a/leetcode/690.\345\221\230\345\267\245\347\232\204\351\207\215\350\246\201\346\200\247.py" +++ "b/leetcode_Python/690.\345\221\230\345\267\245\347\232\204\351\207\215\350\246\201\346\200\247.py" @@ -1,13 +1,13 @@ -# 先用字典存放员工id与员工信息,再将所求员工信息添加到数组中,将重要性累加,并加直系员工信息添加到数组中,循环处理数组 -class Solution(object): - def getImportance(self, employees, id): - d = {e.id:e for e in employees} - res = 0 - q = [] - q.append(d[id]) - while q: - cur = q.pop(0) - res += cur.importance - for i in cur.subordinates: - q.append(d[i]) +# 先用字典存放员工id与员工信息,再将所求员工信息添加到数组中,将重要性累加,并加直系员工信息添加到数组中,循环处理数组 +class Solution(object): + def getImportance(self, employees, id): + d = {e.id:e for e in employees} + res = 0 + q = [] + q.append(d[id]) + while q: + cur = q.pop(0) + res += cur.importance + for i in cur.subordinates: + q.append(d[i]) return res \ No newline at end of file diff --git "a/leetcode/693.\344\272\244\346\233\277\344\275\215\344\272\214\350\277\233\345\210\266\346\225\260.py" "b/leetcode_Python/693.\344\272\244\346\233\277\344\275\215\344\272\214\350\277\233\345\210\266\346\225\260.py" similarity index 97% rename from "leetcode/693.\344\272\244\346\233\277\344\275\215\344\272\214\350\277\233\345\210\266\346\225\260.py" rename to "leetcode_Python/693.\344\272\244\346\233\277\344\275\215\344\272\214\350\277\233\345\210\266\346\225\260.py" index 5704e5b..beeed2d 100644 --- "a/leetcode/693.\344\272\244\346\233\277\344\275\215\344\272\214\350\277\233\345\210\266\346\225\260.py" +++ "b/leetcode_Python/693.\344\272\244\346\233\277\344\275\215\344\272\214\350\277\233\345\210\266\346\225\260.py" @@ -1,34 +1,34 @@ -# 方法一:判断二进制数中是否存在'00'或'11'字符串 -class Solution(object): - def hasAlternatingBits(self, n): - n = bin(n) - return '00' not in n and '11' not in n - -# 方法二:先右移再异或,最后与运算,与运算结果为0则交替 -class Solution(object): - def hasAlternatingBits(self, n): - t = n^(n>>1) - return not (t & t+1) - -# 方法三:遍历二进制数的每个字符,判断相邻两字符是否相等 -class Solution(object): - def hasAlternatingBits(self, n): - n = bin(n)[2:] - for i in range(len(n)-1): - if n[i] == n[i+1]: - return False - return True - -# 方法四:将二进制数的每一位交替放到两个数组中,判断数组是否为同一字符且两数组字符不相等 -class Solution(object): - def hasAlternatingBits(self, n): - if n <= 1: - return True - n = bin(n)[2:] - res1, res2 = [], [] - for i in range(len(n)): - if i%2 == 0: - res1.append(n[i]) - else: - res2.append(n[i]) +# 方法一:判断二进制数中是否存在'00'或'11'字符串 +class Solution(object): + def hasAlternatingBits(self, n): + n = bin(n) + return '00' not in n and '11' not in n + +# 方法二:先右移再异或,最后与运算,与运算结果为0则交替 +class Solution(object): + def hasAlternatingBits(self, n): + t = n^(n>>1) + return not (t & t+1) + +# 方法三:遍历二进制数的每个字符,判断相邻两字符是否相等 +class Solution(object): + def hasAlternatingBits(self, n): + n = bin(n)[2:] + for i in range(len(n)-1): + if n[i] == n[i+1]: + return False + return True + +# 方法四:将二进制数的每一位交替放到两个数组中,判断数组是否为同一字符且两数组字符不相等 +class Solution(object): + def hasAlternatingBits(self, n): + if n <= 1: + return True + n = bin(n)[2:] + res1, res2 = [], [] + for i in range(len(n)): + if i%2 == 0: + res1.append(n[i]) + else: + res2.append(n[i]) return len(set(res1))==1 and len(set(res2))==1 and set(res1)!=set(res2) \ No newline at end of file diff --git "a/leetcode/695.\345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.py" "b/leetcode_Python/695.\345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.py" similarity index 97% rename from "leetcode/695.\345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.py" rename to "leetcode_Python/695.\345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.py" index 5984d7a..82d99fe 100644 --- "a/leetcode/695.\345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.py" +++ "b/leetcode_Python/695.\345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.py" @@ -1,18 +1,18 @@ -class Solution(object): - def maxAreaOfIsland(self, grid): - m, n, maxArea = len(grid), len(grid[0]), 0 - - # 获取岛屿面积 - def getArea(grid, x, y): - # 符合条件的土地,将其置0,并累加四个方向的土地,得到岛屿的面积 - if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: - grid[x][y] = 0 - return 1 + getArea(grid, x + 1, y) + getArea(grid, x - 1, y) + getArea(grid, x, y + 1) + getArea(grid, x, y - 1) - return 0 - - # 遍历每个位置,得到每个位置上的面积并更新最大面积 - for i in range(m): - for j in range(n): - area = getArea(grid, i, j) - maxArea = area if area > maxArea else maxArea - return maxArea +class Solution(object): + def maxAreaOfIsland(self, grid): + m, n, maxArea = len(grid), len(grid[0]), 0 + + # 获取岛屿面积 + def getArea(grid, x, y): + # 符合条件的土地,将其置0,并累加四个方向的土地,得到岛屿的面积 + if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: + grid[x][y] = 0 + return 1 + getArea(grid, x + 1, y) + getArea(grid, x - 1, y) + getArea(grid, x, y + 1) + getArea(grid, x, y - 1) + return 0 + + # 遍历每个位置,得到每个位置上的面积并更新最大面积 + for i in range(m): + for j in range(n): + area = getArea(grid, i, j) + maxArea = area if area > maxArea else maxArea + return maxArea diff --git "a/leetcode/696.\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" "b/leetcode_Python/696.\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" similarity index 98% rename from "leetcode/696.\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" rename to "leetcode_Python/696.\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" index 96a8444..d56801c 100644 --- "a/leetcode/696.\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" +++ "b/leetcode_Python/696.\350\256\241\346\225\260\344\272\214\350\277\233\345\210\266\345\255\220\344\270\262.py" @@ -1,5 +1,5 @@ -# 计算连续的0,1的个数有多少,构成一个数组,找出相邻的两个个数的最小值,然后累加求和 -class Solution(object): - def countBinarySubstrings(self, s): - s = map(len, s.replace('01', '0 1').replace('10', '1 0').split()) +# 计算连续的0,1的个数有多少,构成一个数组,找出相邻的两个个数的最小值,然后累加求和 +class Solution(object): + def countBinarySubstrings(self, s): + s = map(len, s.replace('01', '0 1').replace('10', '1 0').split()) return sum(min(i, j) for i, j in zip(s, s[1:])) \ No newline at end of file diff --git "a/leetcode/697.\346\225\260\347\273\204\347\232\204\345\272\246.py" "b/leetcode_Python/697.\346\225\260\347\273\204\347\232\204\345\272\246.py" similarity index 97% rename from "leetcode/697.\346\225\260\347\273\204\347\232\204\345\272\246.py" rename to "leetcode_Python/697.\346\225\260\347\273\204\347\232\204\345\272\246.py" index 0676862..cd7d89d 100644 --- "a/leetcode/697.\346\225\260\347\273\204\347\232\204\345\272\246.py" +++ "b/leetcode_Python/697.\346\225\260\347\273\204\347\232\204\345\272\246.py" @@ -1,12 +1,12 @@ -# 统计每个元素的个数存放到字典中,将最大频数元素出现的首尾索引保存,找到其中的最小距离 -class Solution(object): - def findShortestSubArray(self, nums): - d = collections.Counter(nums) - left, right = {}, {} - for i, v in enumerate(nums): - # left.setdefault(v, i) - if v not in left: - left[v] = i - right[v] = i - max_v = max(d.values()) +# 统计每个元素的个数存放到字典中,将最大频数元素出现的首尾索引保存,找到其中的最小距离 +class Solution(object): + def findShortestSubArray(self, nums): + d = collections.Counter(nums) + left, right = {}, {} + for i, v in enumerate(nums): + # left.setdefault(v, i) + if v not in left: + left[v] = i + right[v] = i + max_v = max(d.values()) return min(right[k]-left[k]+1 for k in d if d[k]==max_v) \ No newline at end of file diff --git "a/leetcode/700.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\220\234\347\264\242.py" "b/leetcode_Python/700.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\220\234\347\264\242.py" similarity index 97% rename from "leetcode/700.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\220\234\347\264\242.py" rename to "leetcode_Python/700.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\220\234\347\264\242.py" index a97bd6f..1f5cec3 100644 --- "a/leetcode/700.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\220\234\347\264\242.py" +++ "b/leetcode_Python/700.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\220\234\347\264\242.py" @@ -1,11 +1,11 @@ -# 左边结点都比根结点小,右边结点都比根结点大 -class Solution(object): - def searchBST(self, root, val): - if not root: - return - if root.val == val: - return root - elif root.val > val: - return self.searchBST(root.left, val) - else: +# 左边结点都比根结点小,右边结点都比根结点大 +class Solution(object): + def searchBST(self, root, val): + if not root: + return + if root.val == val: + return root + elif root.val > val: + return self.searchBST(root.left, val) + else: return self.searchBST(root.right, val) \ No newline at end of file diff --git "a/leetcode/701.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\217\222\345\205\245\346\223\215\344\275\234.py" "b/leetcode_Python/701.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\217\222\345\205\245\346\223\215\344\275\234.py" similarity index 97% rename from "leetcode/701.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\217\222\345\205\245\346\223\215\344\275\234.py" rename to "leetcode_Python/701.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\217\222\345\205\245\346\223\215\344\275\234.py" index e0ada52..73269e3 100644 --- "a/leetcode/701.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\217\222\345\205\245\346\223\215\344\275\234.py" +++ "b/leetcode_Python/701.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\255\347\232\204\346\217\222\345\205\245\346\223\215\344\275\234.py" @@ -1,23 +1,23 @@ -class Solution(object): - def insertIntoBST(self, root, val): - if not root: - return TreeNode(val) - if val < root.val: - root.left = self.insertIntoBST(root.left, val) - if val > root.val: - root.right = self.insertIntoBST(root.right, val) - return root - -################## 递归思路 ################# -# 方法作用极简化:先判断无结点和1个结点的情况 -# 方法作用描述:参数给一个根和值,将该值的结点插入到根的左右孩子,然后返回插入后的根结点 -# 递归:由于左右孩子有同样需求,给定值结点部分使用递归得到插入后的根结点,将返回结果赋给根结点的左右孩子 -class Solution(object): - def insertIntoBST(self, root, val): - if not root: - return TreeNode(val) - if val < root.val: - root.left = TreeNode(val) - if val > root.val: - root.right = TreeNode(val) +class Solution(object): + def insertIntoBST(self, root, val): + if not root: + return TreeNode(val) + if val < root.val: + root.left = self.insertIntoBST(root.left, val) + if val > root.val: + root.right = self.insertIntoBST(root.right, val) + return root + +################## 递归思路 ################# +# 方法作用极简化:先判断无结点和1个结点的情况 +# 方法作用描述:参数给一个根和值,将该值的结点插入到根的左右孩子,然后返回插入后的根结点 +# 递归:由于左右孩子有同样需求,给定值结点部分使用递归得到插入后的根结点,将返回结果赋给根结点的左右孩子 +class Solution(object): + def insertIntoBST(self, root, val): + if not root: + return TreeNode(val) + if val < root.val: + root.left = TreeNode(val) + if val > root.val: + root.right = TreeNode(val) return root \ No newline at end of file diff --git "a/leetcode/704.\344\272\214\345\210\206\346\237\245\346\211\276.py" "b/leetcode_Python/704.\344\272\214\345\210\206\346\237\245\346\211\276.py" similarity index 96% rename from "leetcode/704.\344\272\214\345\210\206\346\237\245\346\211\276.py" rename to "leetcode_Python/704.\344\272\214\345\210\206\346\237\245\346\211\276.py" index d4ebb7e..2f8fb54 100644 --- "a/leetcode/704.\344\272\214\345\210\206\346\237\245\346\211\276.py" +++ "b/leetcode_Python/704.\344\272\214\345\210\206\346\237\245\346\211\276.py" @@ -1,13 +1,13 @@ -# 取中间索引的值与target值比较大小,再收缩区间 -class Solution(object): - def search(self, nums, target): - l, r = 0, len(nums)-1 - while l <= r: - mid = (l+r)/2 - if nums[mid] > target: - r = mid - 1 - elif nums[mid] < target: - l = mid + 1 - else: - return mid - return -1 +# 取中间索引的值与target值比较大小,再收缩区间 +class Solution(object): + def search(self, nums, target): + l, r = 0, len(nums)-1 + while l <= r: + mid = (l+r)/2 + if nums[mid] > target: + r = mid - 1 + elif nums[mid] < target: + l = mid + 1 + else: + return mid + return -1 diff --git "a/leetcode/705.\350\256\276\350\256\241\345\223\210\345\270\214\351\233\206\345\220\210.py" "b/leetcode_Python/705.\350\256\276\350\256\241\345\223\210\345\270\214\351\233\206\345\220\210.py" similarity index 95% rename from "leetcode/705.\350\256\276\350\256\241\345\223\210\345\270\214\351\233\206\345\220\210.py" rename to "leetcode_Python/705.\350\256\276\350\256\241\345\223\210\345\270\214\351\233\206\345\220\210.py" index e419a77..e11532d 100644 --- "a/leetcode/705.\350\256\276\350\256\241\345\223\210\345\270\214\351\233\206\345\220\210.py" +++ "b/leetcode_Python/705.\350\256\276\350\256\241\345\223\210\345\270\214\351\233\206\345\220\210.py" @@ -1,16 +1,16 @@ -class MyHashSet(object): - - def __init__(self): - self.hash = set() - - def add(self, key): - self.hash.add(key) - - def remove(self, key): - if self.contains(key): - self.hash.remove(key) - - def contains(self, key): - if key in self.hash: - return True +class MyHashSet(object): + + def __init__(self): + self.hash = set() + + def add(self, key): + self.hash.add(key) + + def remove(self, key): + if self.contains(key): + self.hash.remove(key) + + def contains(self, key): + if key in self.hash: + return True return False \ No newline at end of file diff --git "a/leetcode/706.\350\256\276\350\256\241\345\223\210\345\270\214\346\230\240\345\260\204.py" "b/leetcode_Python/706.\350\256\276\350\256\241\345\223\210\345\270\214\346\230\240\345\260\204.py" similarity index 95% rename from "leetcode/706.\350\256\276\350\256\241\345\223\210\345\270\214\346\230\240\345\260\204.py" rename to "leetcode_Python/706.\350\256\276\350\256\241\345\223\210\345\270\214\346\230\240\345\260\204.py" index 3722550..dde6e51 100644 --- "a/leetcode/706.\350\256\276\350\256\241\345\223\210\345\270\214\346\230\240\345\260\204.py" +++ "b/leetcode_Python/706.\350\256\276\350\256\241\345\223\210\345\270\214\346\230\240\345\260\204.py" @@ -1,16 +1,16 @@ -class MyHashMap(object): - - def __init__(self): - self.d = {} - - def put(self, key, value): - self.d[key] = value - - def get(self, key): - if key in self.d: - return self.d[key] - return -1 - - def remove(self, key): - if key in self.d: +class MyHashMap(object): + + def __init__(self): + self.d = {} + + def put(self, key, value): + self.d[key] = value + + def get(self, key): + if key in self.d: + return self.d[key] + return -1 + + def remove(self, key): + if key in self.d: del self.d[key] \ No newline at end of file diff --git "a/leetcode/707.\350\256\276\350\256\241\351\223\276\350\241\250.py" "b/leetcode_Python/707.\350\256\276\350\256\241\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/707.\350\256\276\350\256\241\351\223\276\350\241\250.py" rename to "leetcode_Python/707.\350\256\276\350\256\241\351\223\276\350\241\250.py" index 70694f7..7319e11 100644 --- "a/leetcode/707.\350\256\276\350\256\241\351\223\276\350\241\250.py" +++ "b/leetcode_Python/707.\350\256\276\350\256\241\351\223\276\350\241\250.py" @@ -1,29 +1,29 @@ -# 用数组模拟 -class MyLinkedList(object): - - def __init__(self): - self.arr = [] - - def get(self, index): - if index > len(self.arr)-1 or index < 0: - return -1 - return self.arr[index] - - def addAtHead(self, val): - self.arr.insert(0, val) - - def addAtTail(self, val): - self.arr.append(val) - - def addAtIndex(self, index, val): - if index == len(self.arr): - self.arr.append(val) - elif index > len(self.arr) or index < 0: - return - else: - self.arr.insert(index, val) - - def deleteAtIndex(self, index): - if index > len(self.arr)-1 or index < 0: - return - self.arr.pop(index) +# 用数组模拟 +class MyLinkedList(object): + + def __init__(self): + self.arr = [] + + def get(self, index): + if index > len(self.arr)-1 or index < 0: + return -1 + return self.arr[index] + + def addAtHead(self, val): + self.arr.insert(0, val) + + def addAtTail(self, val): + self.arr.append(val) + + def addAtIndex(self, index, val): + if index == len(self.arr): + self.arr.append(val) + elif index > len(self.arr) or index < 0: + return + else: + self.arr.insert(index, val) + + def deleteAtIndex(self, index): + if index > len(self.arr)-1 or index < 0: + return + self.arr.pop(index) diff --git "a/leetcode/709.\350\275\254\346\215\242\346\210\220\345\260\217\345\206\231\345\255\227\346\257\215.py" "b/leetcode_Python/709.\350\275\254\346\215\242\346\210\220\345\260\217\345\206\231\345\255\227\346\257\215.py" similarity index 98% rename from "leetcode/709.\350\275\254\346\215\242\346\210\220\345\260\217\345\206\231\345\255\227\346\257\215.py" rename to "leetcode_Python/709.\350\275\254\346\215\242\346\210\220\345\260\217\345\206\231\345\255\227\346\257\215.py" index 368ff68..1b321c0 100644 --- "a/leetcode/709.\350\275\254\346\215\242\346\210\220\345\260\217\345\206\231\345\255\227\346\257\215.py" +++ "b/leetcode_Python/709.\350\275\254\346\215\242\346\210\220\345\260\217\345\206\231\345\255\227\346\257\215.py" @@ -1,4 +1,4 @@ -class Solution(object): - def toLowerCase(self, str): - # return str.lower() +class Solution(object): + def toLowerCase(self, str): + # return str.lower() return ''.join(chr(ord(c) + 32) if 'A' <= c <= 'Z' else c for c in str) \ No newline at end of file diff --git "a/leetcode/712.\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\346\234\200\345\260\217ASCII\345\210\240\351\231\244\345\222\214.py" "b/leetcode_Python/712.\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\346\234\200\345\260\217ASCII\345\210\240\351\231\244\345\222\214.py" similarity index 97% rename from "leetcode/712.\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\346\234\200\345\260\217ASCII\345\210\240\351\231\244\345\222\214.py" rename to "leetcode_Python/712.\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\346\234\200\345\260\217ASCII\345\210\240\351\231\244\345\222\214.py" index dbfa295..be3e4f2 100644 --- "a/leetcode/712.\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\346\234\200\345\260\217ASCII\345\210\240\351\231\244\345\222\214.py" +++ "b/leetcode_Python/712.\344\270\244\344\270\252\345\255\227\347\254\246\344\270\262\347\232\204\346\234\200\345\260\217ASCII\345\210\240\351\231\244\345\222\214.py" @@ -1,21 +1,21 @@ -# dp[i][j] 表示s1的前i个字符和s2前j个字符想要相等的最小ASCII删除和 -class Solution(object): - def minimumDeleteSum(self, s1, s2): - n, m = len(s1), len(s2) - dp = [[0]*(m+1) for _ in range(n+1)] - # 初始化首行首列 - for i in range(1, n+1): - dp[i][0] = dp[i-1][0] + ord(s1[i-1]) - for j in range(1, m+1): - dp[0][j] = dp[0][j-1] + ord(s2[j-1]) - # 遍历每个元素,获取状态值 - for i in range(1, n+1): - for j in range(1, m+1): - if s1[i-1] == s2[j-1]: - # 两字符相等,则当前状态等于前一状态 - dp[i][j] = dp[i-1][j-1] - else: - # 两字符不相等,则比较删除哪个字符最终ASCII删除和最小 - dp[i][j] = min(dp[i-1][j] + ord(s1[i-1]), dp[i][j-1] + ord(s2[j-1])) - +# dp[i][j] 表示s1的前i个字符和s2前j个字符想要相等的最小ASCII删除和 +class Solution(object): + def minimumDeleteSum(self, s1, s2): + n, m = len(s1), len(s2) + dp = [[0]*(m+1) for _ in range(n+1)] + # 初始化首行首列 + for i in range(1, n+1): + dp[i][0] = dp[i-1][0] + ord(s1[i-1]) + for j in range(1, m+1): + dp[0][j] = dp[0][j-1] + ord(s2[j-1]) + # 遍历每个元素,获取状态值 + for i in range(1, n+1): + for j in range(1, m+1): + if s1[i-1] == s2[j-1]: + # 两字符相等,则当前状态等于前一状态 + dp[i][j] = dp[i-1][j-1] + else: + # 两字符不相等,则比较删除哪个字符最终ASCII删除和最小 + dp[i][j] = min(dp[i-1][j] + ord(s1[i-1]), dp[i][j-1] + ord(s2[j-1])) + return dp[-1][-1] \ No newline at end of file diff --git "a/leetcode/717.1\346\257\224\347\211\271\344\270\2162\346\257\224\347\211\271\345\255\227\347\254\246.py" "b/leetcode_Python/717.1\346\257\224\347\211\271\344\270\2162\346\257\224\347\211\271\345\255\227\347\254\246.py" similarity index 97% rename from "leetcode/717.1\346\257\224\347\211\271\344\270\2162\346\257\224\347\211\271\345\255\227\347\254\246.py" rename to "leetcode_Python/717.1\346\257\224\347\211\271\344\270\2162\346\257\224\347\211\271\345\255\227\347\254\246.py" index 8555451..dc42728 100644 --- "a/leetcode/717.1\346\257\224\347\211\271\344\270\2162\346\257\224\347\211\271\345\255\227\347\254\246.py" +++ "b/leetcode_Python/717.1\346\257\224\347\211\271\344\270\2162\346\257\224\347\211\271\345\255\227\347\254\246.py" @@ -1,12 +1,12 @@ -# 由于1必须组合,则遇1走两步,遇0走一步,到最后若剩一个字符则为True -class Solution(object): - def isOneBitCharacter(self, bits): - i = 0 - while i < len(bits): - if i == len(bits)-1: - return True - if bits[i] == 1: - i += 2 - else: - i += 1 +# 由于1必须组合,则遇1走两步,遇0走一步,到最后若剩一个字符则为True +class Solution(object): + def isOneBitCharacter(self, bits): + i = 0 + while i < len(bits): + if i == len(bits)-1: + return True + if bits[i] == 1: + i += 2 + else: + i += 1 return False \ No newline at end of file diff --git "a/leetcode/720.\350\257\215\345\205\270\344\270\255\346\234\200\351\225\277\347\232\204\345\215\225\350\257\215.py" "b/leetcode_Python/720.\350\257\215\345\205\270\344\270\255\346\234\200\351\225\277\347\232\204\345\215\225\350\257\215.py" similarity index 97% rename from "leetcode/720.\350\257\215\345\205\270\344\270\255\346\234\200\351\225\277\347\232\204\345\215\225\350\257\215.py" rename to "leetcode_Python/720.\350\257\215\345\205\270\344\270\255\346\234\200\351\225\277\347\232\204\345\215\225\350\257\215.py" index 8435b5e..7e57fcd 100644 --- "a/leetcode/720.\350\257\215\345\205\270\344\270\255\346\234\200\351\225\277\347\232\204\345\215\225\350\257\215.py" +++ "b/leetcode_Python/720.\350\257\215\345\205\270\344\270\255\346\234\200\351\225\277\347\232\204\345\215\225\350\257\215.py" @@ -1,14 +1,14 @@ -class Solution(object): - def longestWord(self, words): - words.sort() - # 数组先保存一个空字符串 - res = [''] - longestWord = '' - for word in words: - # 判断除去最后一个字符的字符串是否在数组中,若在则添加该字符串 - if word[:-1] in res: - res.add(word) - # 新字符串长度大于当前最长字符串时才更新,这样可在同等长度时保留字典序最小的单词 - if len(word) > len(longestWord): - longestWord = word +class Solution(object): + def longestWord(self, words): + words.sort() + # 数组先保存一个空字符串 + res = [''] + longestWord = '' + for word in words: + # 判断除去最后一个字符的字符串是否在数组中,若在则添加该字符串 + if word[:-1] in res: + res.add(word) + # 新字符串长度大于当前最长字符串时才更新,这样可在同等长度时保留字典序最小的单词 + if len(word) > len(longestWord): + longestWord = word return longestWord \ No newline at end of file diff --git "a/leetcode/724.\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\347\264\242\345\274\225.py" "b/leetcode_Python/724.\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\347\264\242\345\274\225.py" similarity index 97% rename from "leetcode/724.\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\347\264\242\345\274\225.py" rename to "leetcode_Python/724.\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\347\264\242\345\274\225.py" index 9a6ff63..b523096 100644 --- "a/leetcode/724.\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\347\264\242\345\274\225.py" +++ "b/leetcode_Python/724.\345\257\273\346\211\276\346\225\260\347\273\204\347\232\204\344\270\255\345\277\203\347\264\242\345\274\225.py" @@ -1,10 +1,10 @@ -# 左右两边通过加减一个数求和,并判断是否相等 -class Solution(object): - def pivotIndex(self, nums): - left, right = 0, sum(nums) - for i, num in enumerate(nums): - right -= num - if left == right: - return i - left += num +# 左右两边通过加减一个数求和,并判断是否相等 +class Solution(object): + def pivotIndex(self, nums): + left, right = 0, sum(nums) + for i, num in enumerate(nums): + right -= num + if left == right: + return i + left += num return -1 \ No newline at end of file diff --git "a/leetcode/725.\345\210\206\351\232\224\351\223\276\350\241\250.py" "b/leetcode_Python/725.\345\210\206\351\232\224\351\223\276\350\241\250.py" similarity index 96% rename from "leetcode/725.\345\210\206\351\232\224\351\223\276\350\241\250.py" rename to "leetcode_Python/725.\345\210\206\351\232\224\351\223\276\350\241\250.py" index e5f4346..2d775a8 100644 --- "a/leetcode/725.\345\210\206\351\232\224\351\223\276\350\241\250.py" +++ "b/leetcode_Python/725.\345\210\206\351\232\224\351\223\276\350\241\250.py" @@ -1,25 +1,25 @@ -class Solution(object): - def splitListToParts(self, root, k): - # 计算链表长度 - count = 0 - head = root - while head: - count += 1 - head = head.next - - # nums代表每组的长度,rem代表前面几组可以再加1个结点 - nums = count/k - rem = count%k - res = [] - for _ in range(k): - head = h = ListNode(0) - for _ in range(nums): - head.next = ListNode(root.val) - head = head.next - root = root.next - if rem: - head.next = ListNode(root.val) - root = root.next - rem -= 1 - res.append(h.next) +class Solution(object): + def splitListToParts(self, root, k): + # 计算链表长度 + count = 0 + head = root + while head: + count += 1 + head = head.next + + # nums代表每组的长度,rem代表前面几组可以再加1个结点 + nums = count/k + rem = count%k + res = [] + for _ in range(k): + head = h = ListNode(0) + for _ in range(nums): + head.next = ListNode(root.val) + head = head.next + root = root.next + if rem: + head.next = ListNode(root.val) + root = root.next + rem -= 1 + res.append(h.next) return res \ No newline at end of file diff --git "a/leetcode/728.\350\207\252\351\231\244\346\225\260.py" "b/leetcode_Python/728.\350\207\252\351\231\244\346\225\260.py" similarity index 97% rename from "leetcode/728.\350\207\252\351\231\244\346\225\260.py" rename to "leetcode_Python/728.\350\207\252\351\231\244\346\225\260.py" index 1a0ae0b..6bb88c5 100644 --- "a/leetcode/728.\350\207\252\351\231\244\346\225\260.py" +++ "b/leetcode_Python/728.\350\207\252\351\231\244\346\225\260.py" @@ -1,14 +1,14 @@ -class Solution(object): - def selfDividingNumbers(self, left, right): - res = [] - for num in range(left, right+1): - # 包含0则继续判断下一位数 - if str(num).find('0') != -1: - continue - # 如果除以自身某位数的余数不为0则跳出循环,否则将该数添加到数组中 - for i in str(num): - if num % int(i) != 0: - break - else: - res.append(num) +class Solution(object): + def selfDividingNumbers(self, left, right): + res = [] + for num in range(left, right+1): + # 包含0则继续判断下一位数 + if str(num).find('0') != -1: + continue + # 如果除以自身某位数的余数不为0则跳出循环,否则将该数添加到数组中 + for i in str(num): + if num % int(i) != 0: + break + else: + res.append(num) return res \ No newline at end of file diff --git "a/leetcode/733.\345\233\276\345\203\217\346\270\262\346\237\223.py" "b/leetcode_Python/733.\345\233\276\345\203\217\346\270\262\346\237\223.py" similarity index 97% rename from "leetcode/733.\345\233\276\345\203\217\346\270\262\346\237\223.py" rename to "leetcode_Python/733.\345\233\276\345\203\217\346\270\262\346\237\223.py" index 5db8c2f..8d7c627 100644 --- "a/leetcode/733.\345\233\276\345\203\217\346\270\262\346\237\223.py" +++ "b/leetcode_Python/733.\345\233\276\345\203\217\346\270\262\346\237\223.py" @@ -1,19 +1,19 @@ -class Solution(object): - def floodFill(self, image, sr, sc, newColor): - d = [(0, 1), (0, -1), (1, 0), (-1, 0)] - m, n, oldColor = len(image), len(image[0]), image[sr][sc] - - # 新值等于就值则返回原图像,避免无限搜索 - if newColor == oldColor: - return image - - # 将符合条件的位置赋新值,再搜索该位置的四个方向是否符合 - def dfs(x, y): - image[x][y] = newColor - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and image[nx][ny] == oldColor: - dfs(nx, ny) - - dfs(sr, sc) +class Solution(object): + def floodFill(self, image, sr, sc, newColor): + d = [(0, 1), (0, -1), (1, 0), (-1, 0)] + m, n, oldColor = len(image), len(image[0]), image[sr][sc] + + # 新值等于就值则返回原图像,避免无限搜索 + if newColor == oldColor: + return image + + # 将符合条件的位置赋新值,再搜索该位置的四个方向是否符合 + def dfs(x, y): + image[x][y] = newColor + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and image[nx][ny] == oldColor: + dfs(nx, ny) + + dfs(sr, sc) return image \ No newline at end of file diff --git "a/leetcode/744.\345\257\273\346\211\276\346\257\224\347\233\256\346\240\207\345\255\227\346\257\215\345\244\247\347\232\204\346\234\200\345\260\217\345\255\227\346\257\215.py" "b/leetcode_Python/744.\345\257\273\346\211\276\346\257\224\347\233\256\346\240\207\345\255\227\346\257\215\345\244\247\347\232\204\346\234\200\345\260\217\345\255\227\346\257\215.py" similarity index 97% rename from "leetcode/744.\345\257\273\346\211\276\346\257\224\347\233\256\346\240\207\345\255\227\346\257\215\345\244\247\347\232\204\346\234\200\345\260\217\345\255\227\346\257\215.py" rename to "leetcode_Python/744.\345\257\273\346\211\276\346\257\224\347\233\256\346\240\207\345\255\227\346\257\215\345\244\247\347\232\204\346\234\200\345\260\217\345\255\227\346\257\215.py" index f7bf6a7..6740c2e 100644 --- "a/leetcode/744.\345\257\273\346\211\276\346\257\224\347\233\256\346\240\207\345\255\227\346\257\215\345\244\247\347\232\204\346\234\200\345\260\217\345\255\227\346\257\215.py" +++ "b/leetcode_Python/744.\345\257\273\346\211\276\346\257\224\347\233\256\346\240\207\345\255\227\346\257\215\345\244\247\347\232\204\346\234\200\345\260\217\345\255\227\346\257\215.py" @@ -1,7 +1,7 @@ -# 数组中比目标字符大的则直接返回,否则返回第一个字符 -class Solution(object): - def nextGreatestLetter(self, letters, target): - for letter in letters: - if letter > target: - return letter +# 数组中比目标字符大的则直接返回,否则返回第一个字符 +class Solution(object): + def nextGreatestLetter(self, letters, target): + for letter in letters: + if letter > target: + return letter return letters[0] \ No newline at end of file diff --git "a/leetcode/746.\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" "b/leetcode_Python/746.\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" similarity index 98% rename from "leetcode/746.\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" rename to "leetcode_Python/746.\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" index 10aca55..83afcde 100644 --- "a/leetcode/746.\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" +++ "b/leetcode_Python/746.\344\275\277\347\224\250\346\234\200\345\260\217\350\212\261\350\264\271\347\210\254\346\245\274\346\242\257.py" @@ -1,10 +1,10 @@ -# 动态规划,找到最优子结构,求到达每一阶的最小成本,倒数第一和倒数第二的最小值即为解 -class Solution(object): - def minCostClimbingStairs(self, cost): - n = len(cost) - dp = {} - # dp = [0] * n # 也可使用数组 - dp[0], dp[1] = cost[0], cost[1] - for i in range(2, n): - dp[i] = min(dp[i-2] + cost[i], dp[i-1] + cost[i]) +# 动态规划,找到最优子结构,求到达每一阶的最小成本,倒数第一和倒数第二的最小值即为解 +class Solution(object): + def minCostClimbingStairs(self, cost): + n = len(cost) + dp = {} + # dp = [0] * n # 也可使用数组 + dp[0], dp[1] = cost[0], cost[1] + for i in range(2, n): + dp[i] = min(dp[i-2] + cost[i], dp[i-1] + cost[i]) return min(dp[n-1], dp[n-2]) \ No newline at end of file diff --git "a/leetcode/747.\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" "b/leetcode_Python/747.\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" similarity index 96% rename from "leetcode/747.\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" rename to "leetcode_Python/747.\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" index 3bf4b3f..7efdb44 100644 --- "a/leetcode/747.\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" +++ "b/leetcode_Python/747.\350\207\263\345\260\221\346\230\257\345\205\266\344\273\226\346\225\260\345\255\227\344\270\244\345\200\215\347\232\204\346\234\200\345\244\247\346\225\260.py" @@ -1,9 +1,9 @@ -class Solution(object): - def dominantIndex(self, nums): - max_num = max(nums) - nums2 = nums[:] - nums.remove(max_num) - for i in nums: - if i*2 > max_num: - return -1 +class Solution(object): + def dominantIndex(self, nums): + max_num = max(nums) + nums2 = nums[:] + nums.remove(max_num) + for i in nums: + if i*2 > max_num: + return -1 return nums2.index(max_num) \ No newline at end of file diff --git "a/leetcode/754.\345\210\260\350\276\276\347\273\210\347\202\271\346\225\260\345\255\227.py" "b/leetcode_Python/754.\345\210\260\350\276\276\347\273\210\347\202\271\346\225\260\345\255\227.py" similarity index 98% rename from "leetcode/754.\345\210\260\350\276\276\347\273\210\347\202\271\346\225\260\345\255\227.py" rename to "leetcode_Python/754.\345\210\260\350\276\276\347\273\210\347\202\271\346\225\260\345\255\227.py" index 644ae7e..a7cc420 100644 --- "a/leetcode/754.\345\210\260\350\276\276\347\273\210\347\202\271\346\225\260\345\255\227.py" +++ "b/leetcode_Python/754.\345\210\260\350\276\276\347\273\210\347\202\271\346\225\260\345\255\227.py" @@ -1,12 +1,12 @@ -# 左右都一样,target取绝对值方便计算。 -# 从0往前一直累加,若总和刚好等于target,则返回当前步数。 -# 若总和大于target并且两者之差为偶数2n,则在第n步往左走同样可刚好到达target,因为左走n步,sum就减少2n步。 -class Solution(object): - def reachNumber(self, target): - step = sum = 0 - target = abs(target) - while 1: - step += 1 - sum += step - if sum == target or (sum > target and (sum-target)%2 == 0): +# 左右都一样,target取绝对值方便计算。 +# 从0往前一直累加,若总和刚好等于target,则返回当前步数。 +# 若总和大于target并且两者之差为偶数2n,则在第n步往左走同样可刚好到达target,因为左走n步,sum就减少2n步。 +class Solution(object): + def reachNumber(self, target): + step = sum = 0 + target = abs(target) + while 1: + step += 1 + sum += step + if sum == target or (sum > target and (sum-target)%2 == 0): return step \ No newline at end of file diff --git "a/leetcode/763.\345\210\222\345\210\206\345\255\227\346\257\215\345\214\272\351\227\264.py" "b/leetcode_Python/763.\345\210\222\345\210\206\345\255\227\346\257\215\345\214\272\351\227\264.py" similarity index 97% rename from "leetcode/763.\345\210\222\345\210\206\345\255\227\346\257\215\345\214\272\351\227\264.py" rename to "leetcode_Python/763.\345\210\222\345\210\206\345\255\227\346\257\215\345\214\272\351\227\264.py" index 3221b80..b4af5f0 100644 --- "a/leetcode/763.\345\210\222\345\210\206\345\255\227\346\257\215\345\214\272\351\227\264.py" +++ "b/leetcode_Python/763.\345\210\222\345\210\206\345\255\227\346\257\215\345\214\272\351\227\264.py" @@ -1,13 +1,13 @@ -# 获取每个字母的最大索引存入字典,遍历每个字母得到区间最大长度 -class Solution(object): - def partitionLabels(self, S): - d = {} - for i, v in enumerate(S): - d[v] = i - left, right, res = 0, d[S[0]], [] - for i, v in enumerate(S): - right = max(right, d[v]) - if i >= right: - res.append(right - left + 1) - left = right + 1 +# 获取每个字母的最大索引存入字典,遍历每个字母得到区间最大长度 +class Solution(object): + def partitionLabels(self, S): + d = {} + for i, v in enumerate(S): + d[v] = i + left, right, res = 0, d[S[0]], [] + for i, v in enumerate(S): + right = max(right, d[v]) + if i >= right: + res.append(right - left + 1) + left = right + 1 return res \ No newline at end of file diff --git "a/leetcode/765.\346\203\205\344\276\243\347\211\265\346\211\213.py" "b/leetcode_Python/765.\346\203\205\344\276\243\347\211\265\346\211\213.py" similarity index 97% rename from "leetcode/765.\346\203\205\344\276\243\347\211\265\346\211\213.py" rename to "leetcode_Python/765.\346\203\205\344\276\243\347\211\265\346\211\213.py" index 657b46c..246170f 100644 --- "a/leetcode/765.\346\203\205\344\276\243\347\211\265\346\211\213.py" +++ "b/leetcode_Python/765.\346\203\205\344\276\243\347\211\265\346\211\213.py" @@ -1,16 +1,16 @@ -# 贪心。遍历偶数位置,若下一位置不是匹配的情侣,则将下一位置与情侣交换位置 -class Solution(object): - def minSwapsCouples(self, row): - res = 0 - for i in range(0, len(row), 2): - if row[i] % 2 == 0: - if row[i+1] != row[i]+1: - res += 1 - j = row.index(row[i]+1) - row[i+1], row[j] = row[j], row[i+1] - else: - if row[i+1] != row[i]-1: - res += 1 - j = row.index(row[i]-1) - row[i+1], row[j] = row[j], row[i+1] +# 贪心。遍历偶数位置,若下一位置不是匹配的情侣,则将下一位置与情侣交换位置 +class Solution(object): + def minSwapsCouples(self, row): + res = 0 + for i in range(0, len(row), 2): + if row[i] % 2 == 0: + if row[i+1] != row[i]+1: + res += 1 + j = row.index(row[i]+1) + row[i+1], row[j] = row[j], row[i+1] + else: + if row[i+1] != row[i]-1: + res += 1 + j = row.index(row[i]-1) + row[i+1], row[j] = row[j], row[i+1] return res \ No newline at end of file diff --git "a/leetcode/766.\346\211\230\346\231\256\345\210\251\350\214\250\347\237\251\351\230\265.py" "b/leetcode_Python/766.\346\211\230\346\231\256\345\210\251\350\214\250\347\237\251\351\230\265.py" similarity index 97% rename from "leetcode/766.\346\211\230\346\231\256\345\210\251\350\214\250\347\237\251\351\230\265.py" rename to "leetcode_Python/766.\346\211\230\346\231\256\345\210\251\350\214\250\347\237\251\351\230\265.py" index bca1a9d..af7e3ab 100644 --- "a/leetcode/766.\346\211\230\346\231\256\345\210\251\350\214\250\347\237\251\351\230\265.py" +++ "b/leetcode_Python/766.\346\211\230\346\231\256\345\210\251\350\214\250\347\237\251\351\230\265.py" @@ -1,16 +1,16 @@ -# 方法一:当前行去掉首元素,上一行去掉尾元素,比较两个数组是否相等 -class Solution(object): - def isToeplitzMatrix(self, matrix): - for i in range(1, len(matrix)): - if matrix[i][1:] != matrix[i-1][:-1]: - return False - return True - -# 方法二:遍历每个元素,如果该元素与右下角元素不相等,则为False -class Solution(object): - def isToeplitzMatrix(self, matrix): - for i in range(len(matrix)-1): - for j in range(len(matrix[0])-1): - if matrix[i][j] != matrix[i+1][j+1]: - return False +# 方法一:当前行去掉首元素,上一行去掉尾元素,比较两个数组是否相等 +class Solution(object): + def isToeplitzMatrix(self, matrix): + for i in range(1, len(matrix)): + if matrix[i][1:] != matrix[i-1][:-1]: + return False + return True + +# 方法二:遍历每个元素,如果该元素与右下角元素不相等,则为False +class Solution(object): + def isToeplitzMatrix(self, matrix): + for i in range(len(matrix)-1): + for j in range(len(matrix[0])-1): + if matrix[i][j] != matrix[i+1][j+1]: + return False return True \ No newline at end of file diff --git "a/leetcode/771.\345\256\235\347\237\263\344\270\216\347\237\263\345\244\264.py" "b/leetcode_Python/771.\345\256\235\347\237\263\344\270\216\347\237\263\345\244\264.py" similarity index 96% rename from "leetcode/771.\345\256\235\347\237\263\344\270\216\347\237\263\345\244\264.py" rename to "leetcode_Python/771.\345\256\235\347\237\263\344\270\216\347\237\263\345\244\264.py" index af8d548..94c3561 100644 --- "a/leetcode/771.\345\256\235\347\237\263\344\270\216\347\237\263\345\244\264.py" +++ "b/leetcode_Python/771.\345\256\235\347\237\263\344\270\216\347\237\263\345\244\264.py" @@ -1,8 +1,8 @@ -# 遍历S,判断元素是否在J中,是则累加 -class Solution(object): - def numJewelsInStones(self, J, S): - count = 0 - for i in S: - if i in J: - count += 1 +# 遍历S,判断元素是否在J中,是则累加 +class Solution(object): + def numJewelsInStones(self, J, S): + count = 0 + for i in S: + if i in J: + count += 1 return count \ No newline at end of file diff --git "a/leetcode/783.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\273\223\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.py" "b/leetcode_Python/783.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\273\223\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.py" similarity index 97% rename from "leetcode/783.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\273\223\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.py" rename to "leetcode_Python/783.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\273\223\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.py" index 46fb65b..dd9ab26 100644 --- "a/leetcode/783.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\273\223\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.py" +++ "b/leetcode_Python/783.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\273\223\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.py" @@ -1,14 +1,14 @@ -# 中序遍历后数组相邻值之差取最小 -class Solution(object): - def minDiffInBST(self, root): - self.res = [] - ans = 999 - def midOrder(root): - if root: - midOrder(root.left) - self.res.append(root.val) - midOrder(root.right) - midOrder(root) - for i in range(len(self.res)-1): - ans = min(ans, self.res[i+1] - self.res[i]) +# 中序遍历后数组相邻值之差取最小 +class Solution(object): + def minDiffInBST(self, root): + self.res = [] + ans = 999 + def midOrder(root): + if root: + midOrder(root.left) + self.res.append(root.val) + midOrder(root.right) + midOrder(root) + for i in range(len(self.res)-1): + ans = min(ans, self.res[i+1] - self.res[i]) return ans \ No newline at end of file diff --git "a/leetcode/784.\345\255\227\346\257\215\345\244\247\345\260\217\345\206\231\345\205\250\346\216\222\345\210\227.py" "b/leetcode_Python/784.\345\255\227\346\257\215\345\244\247\345\260\217\345\206\231\345\205\250\346\216\222\345\210\227.py" similarity index 97% rename from "leetcode/784.\345\255\227\346\257\215\345\244\247\345\260\217\345\206\231\345\205\250\346\216\222\345\210\227.py" rename to "leetcode_Python/784.\345\255\227\346\257\215\345\244\247\345\260\217\345\206\231\345\205\250\346\216\222\345\210\227.py" index 9f5313d..96b3162 100644 --- "a/leetcode/784.\345\255\227\346\257\215\345\244\247\345\260\217\345\206\231\345\205\250\346\216\222\345\210\227.py" +++ "b/leetcode_Python/784.\345\255\227\346\257\215\345\244\247\345\260\217\345\206\231\345\205\250\346\216\222\345\210\227.py" @@ -1,37 +1,37 @@ -# 回溯 -class Solution(object): - def letterCasePermutation(self, S): - # 两个数组分别存放最终结果和临时结果 - res, temp = [''], [] - for s in S: - # 若为数字,则直接添加到每个字符串尾部 - if s.isdigit(): - for v in res: - temp.append(v + s) - # 若为字母,则每个字符串分别添加该字母的小写和大写形式 - else: - for v in res: - temp.append(v + s.lower()) - temp.append(v + s.upper()) - # 将最新结果的临时数组赋给结果数组,临时数组清空 - res, temp = temp, [] - return res - - -# 递归 -class Solution2(object): - def letterCasePermutation(self, S): - - def permutation(s, i, res): - if i >= len(s): - return res - temp = [] - for v in res: - if s[i].isdigit(): - temp.append(v + s[i]) - else: - temp.append(v + s[i].lower()) - temp.append(v + s[i].upper()) - return permutation(s, i + 1, temp) - +# 回溯 +class Solution(object): + def letterCasePermutation(self, S): + # 两个数组分别存放最终结果和临时结果 + res, temp = [''], [] + for s in S: + # 若为数字,则直接添加到每个字符串尾部 + if s.isdigit(): + for v in res: + temp.append(v + s) + # 若为字母,则每个字符串分别添加该字母的小写和大写形式 + else: + for v in res: + temp.append(v + s.lower()) + temp.append(v + s.upper()) + # 将最新结果的临时数组赋给结果数组,临时数组清空 + res, temp = temp, [] + return res + + +# 递归 +class Solution2(object): + def letterCasePermutation(self, S): + + def permutation(s, i, res): + if i >= len(s): + return res + temp = [] + for v in res: + if s[i].isdigit(): + temp.append(v + s[i]) + else: + temp.append(v + s[i].lower()) + temp.append(v + s[i].upper()) + return permutation(s, i + 1, temp) + return permutation(S, 0, ['']) \ No newline at end of file diff --git "a/leetcode/788.\346\227\213\350\275\254\346\225\260\345\255\227.py" "b/leetcode_Python/788.\346\227\213\350\275\254\346\225\260\345\255\227.py" similarity index 97% rename from "leetcode/788.\346\227\213\350\275\254\346\225\260\345\255\227.py" rename to "leetcode_Python/788.\346\227\213\350\275\254\346\225\260\345\255\227.py" index d0c1760..b8cec83 100644 --- "a/leetcode/788.\346\227\213\350\275\254\346\225\260\345\255\227.py" +++ "b/leetcode_Python/788.\346\227\213\350\275\254\346\225\260\345\255\227.py" @@ -1,9 +1,9 @@ -# 包含‘2569’其一,且不包含‘347’ -class Solution(object): - def rotatedDigits(self, N): - res = 0 - for i in range(1, N+1): - s = str(i) - if ('2' in s or '5' in s or '6' in s or '9' in s) and ('3' not in s and '4' not in s and '7' not in s): - res += 1 +# 包含‘2569’其一,且不包含‘347’ +class Solution(object): + def rotatedDigits(self, N): + res = 0 + for i in range(1, N+1): + s = str(i) + if ('2' in s or '5' in s or '6' in s or '9' in s) and ('3' not in s and '4' not in s and '7' not in s): + res += 1 return res \ No newline at end of file diff --git "a/leetcode/791.\350\207\252\345\256\232\344\271\211\345\255\227\347\254\246\344\270\262\346\216\222\345\272\217.py" "b/leetcode_Python/791.\350\207\252\345\256\232\344\271\211\345\255\227\347\254\246\344\270\262\346\216\222\345\272\217.py" similarity index 97% rename from "leetcode/791.\350\207\252\345\256\232\344\271\211\345\255\227\347\254\246\344\270\262\346\216\222\345\272\217.py" rename to "leetcode_Python/791.\350\207\252\345\256\232\344\271\211\345\255\227\347\254\246\344\270\262\346\216\222\345\272\217.py" index a80927d..8b3a12c 100644 --- "a/leetcode/791.\350\207\252\345\256\232\344\271\211\345\255\227\347\254\246\344\270\262\346\216\222\345\272\217.py" +++ "b/leetcode_Python/791.\350\207\252\345\256\232\344\271\211\345\255\227\347\254\246\344\270\262\346\216\222\345\272\217.py" @@ -1,11 +1,11 @@ -# 统计T中字符的个数用字典存放,。先遍历S,按照字典中个数将字符添加到新字符串,并将个数计为0。再遍历T,将剩余字符添加到新字符串 -class Solution(object): - def customSortString(self, S, T): - count = collections.Counter(T) - res = '' - for s in S: - res += s * count[s] - count[s] = 0 - for c in count: - res += c * count[c] +# 统计T中字符的个数用字典存放,。先遍历S,按照字典中个数将字符添加到新字符串,并将个数计为0。再遍历T,将剩余字符添加到新字符串 +class Solution(object): + def customSortString(self, S, T): + count = collections.Counter(T) + res = '' + for s in S: + res += s * count[s] + count[s] = 0 + for c in count: + res += c * count[c] return res \ No newline at end of file diff --git "a/leetcode/796.\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/796.\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" similarity index 98% rename from "leetcode/796.\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/796.\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" index 8918989..c8e4342 100644 --- "a/leetcode/796.\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/796.\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" @@ -1,3 +1,3 @@ -class Solution(object): - def rotateString(self, A, B): +class Solution(object): + def rotateString(self, A, B): return len(A)==len(B) and B in A+A \ No newline at end of file diff --git "a/leetcode/804.\345\224\257\344\270\200\346\221\251\345\260\224\346\226\257\345\257\206\347\240\201\350\257\215.py" "b/leetcode_Python/804.\345\224\257\344\270\200\346\221\251\345\260\224\346\226\257\345\257\206\347\240\201\350\257\215.py" similarity index 98% rename from "leetcode/804.\345\224\257\344\270\200\346\221\251\345\260\224\346\226\257\345\257\206\347\240\201\350\257\215.py" rename to "leetcode_Python/804.\345\224\257\344\270\200\346\221\251\345\260\224\346\226\257\345\257\206\347\240\201\350\257\215.py" index 93511d9..533c97d 100644 --- "a/leetcode/804.\345\224\257\344\270\200\346\221\251\345\260\224\346\226\257\345\257\206\347\240\201\350\257\215.py" +++ "b/leetcode_Python/804.\345\224\257\344\270\200\346\221\251\345\260\224\346\226\257\345\257\206\347\240\201\350\257\215.py" @@ -1,7 +1,7 @@ -class Solution(object): - def uniqueMorseRepresentations(self, words): - code = [".-","-...","-.-.","-..",".","..-.","--.","....","..", - ".---","-.-",".-..","--","-.","---",".--.","--.-",".-.", - "...","-","..-","...-",".--","-..-","-.--","--.."] - res = [''.join(code[ord(char) - ord('a')] for char in word) for word in words] +class Solution(object): + def uniqueMorseRepresentations(self, words): + code = [".-","-...","-.-.","-..",".","..-.","--.","....","..", + ".---","-.-",".-..","--","-.","---",".--.","--.-",".-.", + "...","-","..-","...-",".--","-..-","-.--","--.."] + res = [''.join(code[ord(char) - ord('a')] for char in word) for word in words] return len(set(res)) \ No newline at end of file diff --git "a/leetcode/811.\345\255\220\345\237\237\345\220\215\350\256\277\351\227\256\350\256\241\346\225\260.py" "b/leetcode_Python/811.\345\255\220\345\237\237\345\220\215\350\256\277\351\227\256\350\256\241\346\225\260.py" similarity index 97% rename from "leetcode/811.\345\255\220\345\237\237\345\220\215\350\256\277\351\227\256\350\256\241\346\225\260.py" rename to "leetcode_Python/811.\345\255\220\345\237\237\345\220\215\350\256\277\351\227\256\350\256\241\346\225\260.py" index 84eb12c..592915f 100644 --- "a/leetcode/811.\345\255\220\345\237\237\345\220\215\350\256\277\351\227\256\350\256\241\346\225\260.py" +++ "b/leetcode_Python/811.\345\255\220\345\237\237\345\220\215\350\256\277\351\227\256\350\256\241\346\225\260.py" @@ -1,20 +1,20 @@ -class Solution(object): - def subdomainVisits(self, cpdomains): - d = {} - for i in cpdomains: - # 先切分并保存最低一级域名与次数 - res = i.split() - num = int(res[0]) - addr = res[1] - if addr in d: - d[addr] += num - else: - d[addr] = num - # 再保存父域名和顶级域名的访问次数 - while '.' in addr: - addr = addr[addr.index('.')+1:] - if addr in d: - d[addr] += num - else: - d[addr] = num +class Solution(object): + def subdomainVisits(self, cpdomains): + d = {} + for i in cpdomains: + # 先切分并保存最低一级域名与次数 + res = i.split() + num = int(res[0]) + addr = res[1] + if addr in d: + d[addr] += num + else: + d[addr] = num + # 再保存父域名和顶级域名的访问次数 + while '.' in addr: + addr = addr[addr.index('.')+1:] + if addr in d: + d[addr] += num + else: + d[addr] = num return [str(d[key]) + ' ' + key for key in d] \ No newline at end of file diff --git "a/leetcode/812.\346\234\200\345\244\247\344\270\211\350\247\222\345\275\242\351\235\242\347\247\257.py" "b/leetcode_Python/812.\346\234\200\345\244\247\344\270\211\350\247\222\345\275\242\351\235\242\347\247\257.py" similarity index 97% rename from "leetcode/812.\346\234\200\345\244\247\344\270\211\350\247\222\345\275\242\351\235\242\347\247\257.py" rename to "leetcode_Python/812.\346\234\200\345\244\247\344\270\211\350\247\222\345\275\242\351\235\242\347\247\257.py" index c25c8c5..b92d7b3 100644 --- "a/leetcode/812.\346\234\200\345\244\247\344\270\211\350\247\222\345\275\242\351\235\242\347\247\257.py" +++ "b/leetcode_Python/812.\346\234\200\345\244\247\344\270\211\350\247\222\345\275\242\351\235\242\347\247\257.py" @@ -1,9 +1,9 @@ -# 三角形面积公式 S=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2) -class Solution(object): - def largestTriangleArea(self, points): - res = 0 - for x in points: - for y in points: - for z in points: - res = max(res, 0.5*(x[0]*y[1] + y[0]*z[1] + z[0]*x[1]- x[0]*z[1] - y[0]*x[1] - z[0]*y[1])); +# 三角形面积公式 S=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2) +class Solution(object): + def largestTriangleArea(self, points): + res = 0 + for x in points: + for y in points: + for z in points: + res = max(res, 0.5*(x[0]*y[1] + y[0]*z[1] + z[0]*x[1]- x[0]*z[1] - y[0]*x[1] - z[0]*y[1])); return res \ No newline at end of file diff --git "a/leetcode/814.\344\272\214\345\217\211\346\240\221\345\211\252\346\236\235.py" "b/leetcode_Python/814.\344\272\214\345\217\211\346\240\221\345\211\252\346\236\235.py" similarity index 97% rename from "leetcode/814.\344\272\214\345\217\211\346\240\221\345\211\252\346\236\235.py" rename to "leetcode_Python/814.\344\272\214\345\217\211\346\240\221\345\211\252\346\236\235.py" index 2a9877f..9f76fbc 100644 --- "a/leetcode/814.\344\272\214\345\217\211\346\240\221\345\211\252\346\236\235.py" +++ "b/leetcode_Python/814.\344\272\214\345\217\211\346\240\221\345\211\252\346\236\235.py" @@ -1,21 +1,21 @@ -class Solution(object): - def pruneTree(self, root): - if not root: - return - root.left = self.pruneTree(root.left) - root.right = self.pruneTree(root.right) - if not root.left and not root.right and root.val == 0: - return - return root - -################## 递归思路 ################# -# 方法作用极简化:先判断无结点和1个结点的情况 -# 方法作用描述:参数给一个结点,如果结点为0则返回空,即剪掉该结点,否则返回该结点 -# 递归:由于左右孩子有同样需求,使用递归,然后将返回结果赋给根结点的左右孩子 -class Solution(object): - def pruneTree(self, root): - if not root: - return - if root.val == 0: - return +class Solution(object): + def pruneTree(self, root): + if not root: + return + root.left = self.pruneTree(root.left) + root.right = self.pruneTree(root.right) + if not root.left and not root.right and root.val == 0: + return + return root + +################## 递归思路 ################# +# 方法作用极简化:先判断无结点和1个结点的情况 +# 方法作用描述:参数给一个结点,如果结点为0则返回空,即剪掉该结点,否则返回该结点 +# 递归:由于左右孩子有同样需求,使用递归,然后将返回结果赋给根结点的左右孩子 +class Solution(object): + def pruneTree(self, root): + if not root: + return + if root.val == 0: + return return root \ No newline at end of file diff --git "a/leetcode/817.\351\223\276\350\241\250\347\273\204\344\273\266.py" "b/leetcode_Python/817.\351\223\276\350\241\250\347\273\204\344\273\266.py" similarity index 97% rename from "leetcode/817.\351\223\276\350\241\250\347\273\204\344\273\266.py" rename to "leetcode_Python/817.\351\223\276\350\241\250\347\273\204\344\273\266.py" index 7b49ed5..692414b 100644 --- "a/leetcode/817.\351\223\276\350\241\250\347\273\204\344\273\266.py" +++ "b/leetcode_Python/817.\351\223\276\350\241\250\347\273\204\344\273\266.py" @@ -1,10 +1,10 @@ -# 将G的元素放入Set,遍历head,若遇到一个元素在Set中并且下一个元素为空或者不在Set中,则将组件个数加1 -class Solution(object): - def numComponents(self, head, G): - count = 0 - g = set(G) - while head: - if head.val in g and (not head.next or head.next.val not in g): - count += 1 - head = head.next +# 将G的元素放入Set,遍历head,若遇到一个元素在Set中并且下一个元素为空或者不在Set中,则将组件个数加1 +class Solution(object): + def numComponents(self, head, G): + count = 0 + g = set(G) + while head: + if head.val in g and (not head.next or head.next.val not in g): + count += 1 + head = head.next return count \ No newline at end of file diff --git "a/leetcode/819.\346\234\200\345\270\270\350\247\201\347\232\204\350\257\215.py" "b/leetcode_Python/819.\346\234\200\345\270\270\350\247\201\347\232\204\350\257\215.py" similarity index 98% rename from "leetcode/819.\346\234\200\345\270\270\350\247\201\347\232\204\350\257\215.py" rename to "leetcode_Python/819.\346\234\200\345\270\270\350\247\201\347\232\204\350\257\215.py" index 2fe3a58..afafa3c 100644 --- "a/leetcode/819.\346\234\200\345\270\270\350\247\201\347\232\204\350\257\215.py" +++ "b/leetcode_Python/819.\346\234\200\345\270\270\350\247\201\347\232\204\350\257\215.py" @@ -1,15 +1,15 @@ -class Solution(object): - def mostCommonWord(self, paragraph, banned): - # 先按空格切分,再按逗号切分,然后去除每个词的标点字符 - words = [w.strip("!?';.") for word in paragraph.lower().split(' ') for w in word.split(',')] - # 将不包含在禁用列表的单词添加到字典并累加次数 - d = {} - for word in words: - # 按逗号切分可能带来空单词,需要判断单词是否存在 - if word and word not in banned: - d[word] = d.get(word, 0) + 1 - # 找出最大次数的单词 - max_times = max(d.values()) - for key in d: - if d[key] == max_times: +class Solution(object): + def mostCommonWord(self, paragraph, banned): + # 先按空格切分,再按逗号切分,然后去除每个词的标点字符 + words = [w.strip("!?';.") for word in paragraph.lower().split(' ') for w in word.split(',')] + # 将不包含在禁用列表的单词添加到字典并累加次数 + d = {} + for word in words: + # 按逗号切分可能带来空单词,需要判断单词是否存在 + if word and word not in banned: + d[word] = d.get(word, 0) + 1 + # 找出最大次数的单词 + max_times = max(d.values()) + for key in d: + if d[key] == max_times: return key \ No newline at end of file diff --git "a/leetcode/821.\345\255\227\347\254\246\347\232\204\346\234\200\347\237\255\350\267\235\347\246\273.py" "b/leetcode_Python/821.\345\255\227\347\254\246\347\232\204\346\234\200\347\237\255\350\267\235\347\246\273.py" similarity index 97% rename from "leetcode/821.\345\255\227\347\254\246\347\232\204\346\234\200\347\237\255\350\267\235\347\246\273.py" rename to "leetcode_Python/821.\345\255\227\347\254\246\347\232\204\346\234\200\347\237\255\350\267\235\347\246\273.py" index 84a45d0..f9dc0ee 100644 --- "a/leetcode/821.\345\255\227\347\254\246\347\232\204\346\234\200\347\237\255\350\267\235\347\246\273.py" +++ "b/leetcode_Python/821.\345\255\227\347\254\246\347\232\204\346\234\200\347\237\255\350\267\235\347\246\273.py" @@ -1,13 +1,13 @@ -class Solution(object): - def shortestToChar(self, S, C): - res = [] - for i in range(len(S)): - # 分别从当前索引的左边和右边找第一个C字符 - left, right = S[i::-1].find(C), S[i:].find(C) - # -1表示没有 - if left == -1: - left = 10000 - if right == -1: - right = 10000 - res.append(min(left , right)) +class Solution(object): + def shortestToChar(self, S, C): + res = [] + for i in range(len(S)): + # 分别从当前索引的左边和右边找第一个C字符 + left, right = S[i::-1].find(C), S[i:].find(C) + # -1表示没有 + if left == -1: + left = 10000 + if right == -1: + right = 10000 + res.append(min(left , right)) return res \ No newline at end of file diff --git "a/leetcode/824.\345\261\261\347\276\212\346\213\211\344\270\201\346\226\207.py" "b/leetcode_Python/824.\345\261\261\347\276\212\346\213\211\344\270\201\346\226\207.py" similarity index 96% rename from "leetcode/824.\345\261\261\347\276\212\346\213\211\344\270\201\346\226\207.py" rename to "leetcode_Python/824.\345\261\261\347\276\212\346\213\211\344\270\201\346\226\207.py" index 914e00b..fb76ad4 100644 --- "a/leetcode/824.\345\261\261\347\276\212\346\213\211\344\270\201\346\226\207.py" +++ "b/leetcode_Python/824.\345\261\261\347\276\212\346\213\211\344\270\201\346\226\207.py" @@ -1,13 +1,13 @@ -class Solution(object): - def toGoatLatin(self, S): - res = [] - i = 1 - for s in S.split(): - if s[0] in 'aeiouAEIOU': - s += 'ma' - else: - s = s[1:] + s[0] + 'ma' - s += 'a'*i - i += 1 - res.append(s) +class Solution(object): + def toGoatLatin(self, S): + res = [] + i = 1 + for s in S.split(): + if s[0] in 'aeiouAEIOU': + s += 'ma' + else: + s = s[1:] + s[0] + 'ma' + s += 'a'*i + i += 1 + res.append(s) return ' '.join(res) \ No newline at end of file diff --git "a/leetcode/825.\351\200\202\351\276\204\347\232\204\346\234\213\345\217\213.py" "b/leetcode_Python/825.\351\200\202\351\276\204\347\232\204\346\234\213\345\217\213.py" similarity index 97% rename from "leetcode/825.\351\200\202\351\276\204\347\232\204\346\234\213\345\217\213.py" rename to "leetcode_Python/825.\351\200\202\351\276\204\347\232\204\346\234\213\345\217\213.py" index 4ff38e9..be5fea1 100644 --- "a/leetcode/825.\351\200\202\351\276\204\347\232\204\346\234\213\345\217\213.py" +++ "b/leetcode_Python/825.\351\200\202\351\276\204\347\232\204\346\234\213\345\217\213.py" @@ -1,14 +1,14 @@ -class Solution(object): - def numFriendRequests(self, ages): - count = [0]*121 - for age in ages: - count[age] += 1 - res = 0 - for ageB in range(1, 121): - for ageA in range(ageB, 121): - if (ageB <= 0.5*ageA+7) or (ageB > ageA) or (ageB > 100 and ageA < 100): - continue - res += count[ageA] * count[ageB] - if ageA == ageB: - res -= count[ageA] +class Solution(object): + def numFriendRequests(self, ages): + count = [0]*121 + for age in ages: + count[age] += 1 + res = 0 + for ageB in range(1, 121): + for ageA in range(ageB, 121): + if (ageB <= 0.5*ageA+7) or (ageB > ageA) or (ageB > 100 and ageA < 100): + continue + res += count[ageA] * count[ageB] + if ageA == ageB: + res -= count[ageA] return res \ No newline at end of file diff --git "a/leetcode/830.\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" "b/leetcode_Python/830.\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" similarity index 97% rename from "leetcode/830.\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" rename to "leetcode_Python/830.\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" index 342dfc0..2359595 100644 --- "a/leetcode/830.\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" +++ "b/leetcode_Python/830.\350\276\203\345\244\247\345\210\206\347\273\204\347\232\204\344\275\215\347\275\256.py" @@ -1,14 +1,14 @@ -# 遍历字符串,i记录起始索引,j记录终止索引,若两索引间距≥3,则将其索引区间添加到数组中 -class Solution(object): - def largeGroupPositions(self, S): - j = 0 - res = [] - while j < len(S): - i = j - j += 1 - # j位置有值,并且与i位置值相等 - while j < len(S) and S[i] == S[j]: - j += 1 - if j-i >= 3: - res.append([i, j-1]) +# 遍历字符串,i记录起始索引,j记录终止索引,若两索引间距≥3,则将其索引区间添加到数组中 +class Solution(object): + def largeGroupPositions(self, S): + j = 0 + res = [] + while j < len(S): + i = j + j += 1 + # j位置有值,并且与i位置值相等 + while j < len(S) and S[i] == S[j]: + j += 1 + if j-i >= 3: + res.append([i, j-1]) return res \ No newline at end of file diff --git "a/leetcode/832.\347\277\273\350\275\254\345\233\276\345\203\217.py" "b/leetcode_Python/832.\347\277\273\350\275\254\345\233\276\345\203\217.py" similarity index 97% rename from "leetcode/832.\347\277\273\350\275\254\345\233\276\345\203\217.py" rename to "leetcode_Python/832.\347\277\273\350\275\254\345\233\276\345\203\217.py" index 2d3bad2..c271f3b 100644 --- "a/leetcode/832.\347\277\273\350\275\254\345\233\276\345\203\217.py" +++ "b/leetcode_Python/832.\347\277\273\350\275\254\345\233\276\345\203\217.py" @@ -1,7 +1,7 @@ -# 将逆序后的数组映射到自定义函数,元素为1则减1,元素为0则加1 -class Solution(object): - def flipAndInvertImage(self, A): - res = [] - for a in A: - res.append(list(map(lambda x: x-1 if x else x+1, a[::-1]))) +# 将逆序后的数组映射到自定义函数,元素为1则减1,元素为0则加1 +class Solution(object): + def flipAndInvertImage(self, A): + res = [] + for a in A: + res.append(list(map(lambda x: x-1 if x else x+1, a[::-1]))) return res \ No newline at end of file diff --git "a/leetcode/834.\346\240\221\344\270\255\350\267\235\347\246\273\344\271\213\345\222\214.py" "b/leetcode_Python/834.\346\240\221\344\270\255\350\267\235\347\246\273\344\271\213\345\222\214.py" similarity index 96% rename from "leetcode/834.\346\240\221\344\270\255\350\267\235\347\246\273\344\271\213\345\222\214.py" rename to "leetcode_Python/834.\346\240\221\344\270\255\350\267\235\347\246\273\344\271\213\345\222\214.py" index 319692d..fdc3083 100644 --- "a/leetcode/834.\346\240\221\344\270\255\350\267\235\347\246\273\344\271\213\345\222\214.py" +++ "b/leetcode_Python/834.\346\240\221\344\270\255\350\267\235\347\246\273\344\271\213\345\222\214.py" @@ -1,31 +1,31 @@ -class Solution(object): - def sumOfDistancesInTree(self, N, edges): - d = collections.defaultdict(set) - for s,t in edges: - d[s].add(t) - d[t].add(s) - - count = [1]*N - res = [0]*N - - # 计算孩子到根的距离 - def dfs(root, vis): - vis.add(root) - for i in d[root]: - if i not in vis: - dfs(i, vis) - # res[i]是用i作为根,所有孩子到i的距离之和 - count[root] += count[i] - res[root] += res[i] + count[i] - - # 计算根到孩子的距离 - def dfs2(root, vis): - vis.add(root) - for i in d[root]: - if i not in vis: - res[i] = res[root] - count[i] + N-count[i] - dfs2(i, vis) - - dfs(0, set()) - dfs2(0, set()) +class Solution(object): + def sumOfDistancesInTree(self, N, edges): + d = collections.defaultdict(set) + for s,t in edges: + d[s].add(t) + d[t].add(s) + + count = [1]*N + res = [0]*N + + # 计算孩子到根的距离 + def dfs(root, vis): + vis.add(root) + for i in d[root]: + if i not in vis: + dfs(i, vis) + # res[i]是用i作为根,所有孩子到i的距离之和 + count[root] += count[i] + res[root] += res[i] + count[i] + + # 计算根到孩子的距离 + def dfs2(root, vis): + vis.add(root) + for i in d[root]: + if i not in vis: + res[i] = res[root] - count[i] + N-count[i] + dfs2(i, vis) + + dfs(0, set()) + dfs2(0, set()) return res \ No newline at end of file diff --git "a/leetcode/836.\347\237\251\345\275\242\351\207\215\345\217\240.py" "b/leetcode_Python/836.\347\237\251\345\275\242\351\207\215\345\217\240.py" similarity index 98% rename from "leetcode/836.\347\237\251\345\275\242\351\207\215\345\217\240.py" rename to "leetcode_Python/836.\347\237\251\345\275\242\351\207\215\345\217\240.py" index 5abf577..0005eb0 100644 --- "a/leetcode/836.\347\237\251\345\275\242\351\207\215\345\217\240.py" +++ "b/leetcode_Python/836.\347\237\251\345\275\242\351\207\215\345\217\240.py" @@ -1,6 +1,6 @@ -# 若有重叠,则横坐标上,矩形2的左下角小于矩形1的右上角,矩形2的右上角大于矩形1的左小角,纵坐标同理 -class Solution(object): - def isRectangleOverlap(self, rec1, rec2): - x1, y1, x2, y2 = rec1 - x3, y3, x4, y4 = rec2 +# 若有重叠,则横坐标上,矩形2的左下角小于矩形1的右上角,矩形2的右上角大于矩形1的左小角,纵坐标同理 +class Solution(object): + def isRectangleOverlap(self, rec1, rec2): + x1, y1, x2, y2 = rec1 + x3, y3, x4, y4 = rec2 return (x3-x2)*(x4-x1)<0 and (y3-y2)*(y4-y1)<0 \ No newline at end of file diff --git "a/leetcode/840.\347\237\251\351\230\265\344\270\255\347\232\204\345\271\273\346\226\271.py" "b/leetcode_Python/840.\347\237\251\351\230\265\344\270\255\347\232\204\345\271\273\346\226\271.py" similarity index 98% rename from "leetcode/840.\347\237\251\351\230\265\344\270\255\347\232\204\345\271\273\346\226\271.py" rename to "leetcode_Python/840.\347\237\251\351\230\265\344\270\255\347\232\204\345\271\273\346\226\271.py" index a7af77e..45a3df7 100644 --- "a/leetcode/840.\347\237\251\351\230\265\344\270\255\347\232\204\345\271\273\346\226\271.py" +++ "b/leetcode_Python/840.\347\237\251\351\230\265\344\270\255\347\232\204\345\271\273\346\226\271.py" @@ -1,46 +1,46 @@ -# 方法一:暴力破解 -class Solution(object): - def numMagicSquaresInside(self, grid): - count = 0 - for i in range(len(grid)-2): - for j in range(len(grid[0])-2): - # 判断矩阵是否在1-9之间 - magic = sorted([grid[i][j], grid[i][j+1], grid[i][j+2], - grid[i+1][j], grid[i+1][j+1], grid[i+1][j+2], - grid[i+2][j], grid[i+2][j+1], grid[i+2][j+2]]) - if magic[0] < 1 or magic[-1] > 9: - continue - # 三行 - g1 = grid[i][j] + grid[i][j+1] + grid[i][j+2] - g2 = grid[i+1][j] + grid[i+1][j+1] + grid[i+1][j+2] - g3 = grid[i+2][j] + grid[i+2][j+1] + grid[i+2][j+2] - # 三列 - g4 = grid[i][j] + grid[i+1][j] + grid[i+2][j] - g5 = grid[i][j+1] + grid[i+1][j+1] + grid[i+2][j+1] - g6 = grid[i][j+2] + grid[i+1][j+2] + grid[i+2][j+2] - # 两对角 - g7 = grid[i][j] + grid[i+1][j+1] + grid[i+2][j+2] - g8 = grid[i][j+2] + grid[i+1][j+1] + grid[i+2][j] - # 所有值相等 - if len(set([g1, g2, g3, g4, g5, g6, g7, g8])) == 1: - count += 1 - return count - - -# 方法二:幻方矩阵中心须为5,行列对角的和为15 -class Solution(object): - def numMagicSquaresInside(self, grid): - counte = 0 - for row in range(len(grid) - 2): - for col in range(len(grid[0]) - 2): - sub_matrix = [[grid[row + i][col + j] for j in range(3)] for i in range(3)] - if self.magic_square(sub_matrix): - counte += 1 - return counte - - def magic_square(self, matrix): - is_number_right = all(1 <= matrix[i][j] <= 9 for i in range(3) for j in range(3)) - is_row_right = all(sum(row) == 15 for row in matrix) - is_col_right = all(sum(col) == 15 for col in [[matrix[i][j] for i in range(3)] for j in range(3)]) - is_diagonal_right = matrix[1][1] == 5 and matrix[0][0] + matrix[-1][-1] == 10 and matrix[0][-1] + matrix[-1][0] == 10 +# 方法一:暴力破解 +class Solution(object): + def numMagicSquaresInside(self, grid): + count = 0 + for i in range(len(grid)-2): + for j in range(len(grid[0])-2): + # 判断矩阵是否在1-9之间 + magic = sorted([grid[i][j], grid[i][j+1], grid[i][j+2], + grid[i+1][j], grid[i+1][j+1], grid[i+1][j+2], + grid[i+2][j], grid[i+2][j+1], grid[i+2][j+2]]) + if magic[0] < 1 or magic[-1] > 9: + continue + # 三行 + g1 = grid[i][j] + grid[i][j+1] + grid[i][j+2] + g2 = grid[i+1][j] + grid[i+1][j+1] + grid[i+1][j+2] + g3 = grid[i+2][j] + grid[i+2][j+1] + grid[i+2][j+2] + # 三列 + g4 = grid[i][j] + grid[i+1][j] + grid[i+2][j] + g5 = grid[i][j+1] + grid[i+1][j+1] + grid[i+2][j+1] + g6 = grid[i][j+2] + grid[i+1][j+2] + grid[i+2][j+2] + # 两对角 + g7 = grid[i][j] + grid[i+1][j+1] + grid[i+2][j+2] + g8 = grid[i][j+2] + grid[i+1][j+1] + grid[i+2][j] + # 所有值相等 + if len(set([g1, g2, g3, g4, g5, g6, g7, g8])) == 1: + count += 1 + return count + + +# 方法二:幻方矩阵中心须为5,行列对角的和为15 +class Solution(object): + def numMagicSquaresInside(self, grid): + counte = 0 + for row in range(len(grid) - 2): + for col in range(len(grid[0]) - 2): + sub_matrix = [[grid[row + i][col + j] for j in range(3)] for i in range(3)] + if self.magic_square(sub_matrix): + counte += 1 + return counte + + def magic_square(self, matrix): + is_number_right = all(1 <= matrix[i][j] <= 9 for i in range(3) for j in range(3)) + is_row_right = all(sum(row) == 15 for row in matrix) + is_col_right = all(sum(col) == 15 for col in [[matrix[i][j] for i in range(3)] for j in range(3)]) + is_diagonal_right = matrix[1][1] == 5 and matrix[0][0] + matrix[-1][-1] == 10 and matrix[0][-1] + matrix[-1][0] == 10 return is_number_right and is_row_right and is_col_right and is_diagonal_right \ No newline at end of file diff --git "a/leetcode/841.\351\222\245\345\214\231\345\222\214\346\210\277\351\227\264.py" "b/leetcode_Python/841.\351\222\245\345\214\231\345\222\214\346\210\277\351\227\264.py" similarity index 96% rename from "leetcode/841.\351\222\245\345\214\231\345\222\214\346\210\277\351\227\264.py" rename to "leetcode_Python/841.\351\222\245\345\214\231\345\222\214\346\210\277\351\227\264.py" index eb2f2aa..caa7599 100644 --- "a/leetcode/841.\351\222\245\345\214\231\345\222\214\346\210\277\351\227\264.py" +++ "b/leetcode_Python/841.\351\222\245\345\214\231\345\222\214\346\210\277\351\227\264.py" @@ -1,30 +1,30 @@ -# 广度优先搜索 -class Solution(object): - def canVisitAllRooms(self, rooms): - queue = rooms[0] - visit = [0] - while queue: - temp = queue.pop() - if temp in visit: - continue - queue += rooms[temp] - visit.append(temp) - return len(visit) == len(rooms) - - -# 深度优先搜索 -class Solution2(object): - def canVisitAllRooms(self, rooms): - def dfs(room): - # 将当前房间添加到钥匙集合 - keys.add(room) - # 遍历当前房间里的钥匙 - for key in rooms[room]: - # 若该钥匙未在集合中 - if key not in keys: - # 则递归搜索对应房间内的钥匙 - dfs(key) - - keys = set() - dfs(0) +# 广度优先搜索 +class Solution(object): + def canVisitAllRooms(self, rooms): + queue = rooms[0] + visit = [0] + while queue: + temp = queue.pop() + if temp in visit: + continue + queue += rooms[temp] + visit.append(temp) + return len(visit) == len(rooms) + + +# 深度优先搜索 +class Solution2(object): + def canVisitAllRooms(self, rooms): + def dfs(room): + # 将当前房间添加到钥匙集合 + keys.add(room) + # 遍历当前房间里的钥匙 + for key in rooms[room]: + # 若该钥匙未在集合中 + if key not in keys: + # 则递归搜索对应房间内的钥匙 + dfs(key) + + keys = set() + dfs(0) return len(keys) == len(rooms) \ No newline at end of file diff --git "a/leetcode/844.\346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/844.\346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "leetcode/844.\346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/844.\346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.py" index c6dd846..91b620d 100644 --- "a/leetcode/844.\346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/844.\346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.py" @@ -1,15 +1,15 @@ -# 栈的先进先出,不是'#'就进栈,遇到'#'就出栈 -class Solution(object): - def backspaceCompare(self, S, T): - res1, res2 = [], [] - for s in S: - if s == '#' and res1: - res1.pop() - elif s != '#': - res1.append(s) - for t in T: - if t == '#' and res2: - res2.pop() - elif t != '#': - res2.append(t) +# 栈的先进先出,不是'#'就进栈,遇到'#'就出栈 +class Solution(object): + def backspaceCompare(self, S, T): + res1, res2 = [], [] + for s in S: + if s == '#' and res1: + res1.pop() + elif s != '#': + res1.append(s) + for t in T: + if t == '#' and res2: + res2.pop() + elif t != '#': + res2.append(t) return ''.join(res1) == ''.join(res2) \ No newline at end of file diff --git "a/leetcode/849.\345\210\260\346\234\200\350\277\221\347\232\204\344\272\272\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273.py" "b/leetcode_Python/849.\345\210\260\346\234\200\350\277\221\347\232\204\344\272\272\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273.py" similarity index 97% rename from "leetcode/849.\345\210\260\346\234\200\350\277\221\347\232\204\344\272\272\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273.py" rename to "leetcode_Python/849.\345\210\260\346\234\200\350\277\221\347\232\204\344\272\272\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273.py" index 9e18b92..46eadc3 100644 --- "a/leetcode/849.\345\210\260\346\234\200\350\277\221\347\232\204\344\272\272\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273.py" +++ "b/leetcode_Python/849.\345\210\260\346\234\200\350\277\221\347\232\204\344\272\272\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273.py" @@ -1,15 +1,15 @@ -# 左右两边0的个数即为最大距离,中间0的个数的一半即为最大距离,再比较出最大 -class Solution(object): - def maxDistToClosest(self, seats): - pre, res = -1, 1 - for i in range(len(seats)): - if seats[i]: - # 左边 - if pre < 0: - res = i - # 中间 - else: - res = max(res, (i-pre)/2) - pre = i - # 右边 +# 左右两边0的个数即为最大距离,中间0的个数的一半即为最大距离,再比较出最大 +class Solution(object): + def maxDistToClosest(self, seats): + pre, res = -1, 1 + for i in range(len(seats)): + if seats[i]: + # 左边 + if pre < 0: + res = i + # 中间 + else: + res = max(res, (i-pre)/2) + pre = i + # 右边 return max(res, len(seats)-1-pre) \ No newline at end of file diff --git "a/leetcode/852.\345\261\261\350\204\211\346\225\260\347\273\204\347\232\204\345\263\260\351\241\266\347\264\242\345\274\225.py" "b/leetcode_Python/852.\345\261\261\350\204\211\346\225\260\347\273\204\347\232\204\345\263\260\351\241\266\347\264\242\345\274\225.py" similarity index 97% rename from "leetcode/852.\345\261\261\350\204\211\346\225\260\347\273\204\347\232\204\345\263\260\351\241\266\347\264\242\345\274\225.py" rename to "leetcode_Python/852.\345\261\261\350\204\211\346\225\260\347\273\204\347\232\204\345\263\260\351\241\266\347\264\242\345\274\225.py" index 9cfabe0..e4e2d06 100644 --- "a/leetcode/852.\345\261\261\350\204\211\346\225\260\347\273\204\347\232\204\345\263\260\351\241\266\347\264\242\345\274\225.py" +++ "b/leetcode_Python/852.\345\261\261\350\204\211\346\225\260\347\273\204\347\232\204\345\263\260\351\241\266\347\264\242\345\274\225.py" @@ -1,12 +1,12 @@ -# 方法一:已经确定为山脉的数组,找最大值的索引即可 -class Solution(object): - def peakIndexInMountainArray(self, A): - return A.index(max(A)) - -# 方法二:遍历数组得到第一个出现递减的值的索引 -class Solution(object): - def peakIndexInMountainArray(self, A): - for i in range(1, len(A)-1): - if A[i] > A[i+1]: - return i - +# 方法一:已经确定为山脉的数组,找最大值的索引即可 +class Solution(object): + def peakIndexInMountainArray(self, A): + return A.index(max(A)) + +# 方法二:遍历数组得到第一个出现递减的值的索引 +class Solution(object): + def peakIndexInMountainArray(self, A): + for i in range(1, len(A)-1): + if A[i] > A[i+1]: + return i + diff --git "a/leetcode/859.\344\272\262\345\257\206\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/859.\344\272\262\345\257\206\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "leetcode/859.\344\272\262\345\257\206\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/859.\344\272\262\345\257\206\345\255\227\347\254\246\344\270\262.py" index 5121df7..2815a87 100644 --- "a/leetcode/859.\344\272\262\345\257\206\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/859.\344\272\262\345\257\206\345\255\227\347\254\246\344\270\262.py" @@ -1,18 +1,18 @@ -class Solution(object): - def buddyStrings(self, A, B): - # 长度不相等 - if len(A) != len(B): - return False - # 找出不相等的字符 - res = [] - for i in range(len(A)): - if A[i] != B[i]: - res.append(A[i]+B[i]) - # 刚好两个位置不相等 - if len(res) == 2: - return res[0][::-1] == res[1] - # 全部相等,则找出A是否含有两个相等的字符交换 - if len(res) == 0: - return any(i>1 for i in collections.Counter(A).values()) - # 其他情况 +class Solution(object): + def buddyStrings(self, A, B): + # 长度不相等 + if len(A) != len(B): + return False + # 找出不相等的字符 + res = [] + for i in range(len(A)): + if A[i] != B[i]: + res.append(A[i]+B[i]) + # 刚好两个位置不相等 + if len(res) == 2: + return res[0][::-1] == res[1] + # 全部相等,则找出A是否含有两个相等的字符交换 + if len(res) == 0: + return any(i>1 for i in collections.Counter(A).values()) + # 其他情况 return False \ No newline at end of file diff --git "a/leetcode/860.\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" "b/leetcode_Python/860.\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" similarity index 96% rename from "leetcode/860.\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" rename to "leetcode_Python/860.\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" index 2e3ef19..c4295d9 100644 --- "a/leetcode/860.\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" +++ "b/leetcode_Python/860.\346\237\240\346\252\254\346\260\264\346\211\276\351\233\266.py" @@ -1,23 +1,23 @@ -# 三种情况分别讨论 -class Solution(object): - def lemonadeChange(self, bills): - d = {5:0, 10:0, 20:0} - for b in bills: - if b == 5: - d[5] += 1 - elif b == 10: - if d[5] < 1: - return False - d[5] -= 1 - d[10] += 1 - else: - if d[5] > 0 and d[10] > 0: - d[5] -= 1 - d[10] -= 1 - d[20] += 1 - elif d[5] > 2: - d[5] -= 3 - d[20] += 1 - else: - return False +# 三种情况分别讨论 +class Solution(object): + def lemonadeChange(self, bills): + d = {5:0, 10:0, 20:0} + for b in bills: + if b == 5: + d[5] += 1 + elif b == 10: + if d[5] < 1: + return False + d[5] -= 1 + d[10] += 1 + else: + if d[5] > 0 and d[10] > 0: + d[5] -= 1 + d[10] -= 1 + d[20] += 1 + elif d[5] > 2: + d[5] -= 3 + d[20] += 1 + else: + return False return True \ No newline at end of file diff --git "a/leetcode/861.\347\277\273\350\275\254\347\237\251\351\230\265\345\220\216\347\232\204\345\276\227\345\210\206.py" "b/leetcode_Python/861.\347\277\273\350\275\254\347\237\251\351\230\265\345\220\216\347\232\204\345\276\227\345\210\206.py" similarity index 97% rename from "leetcode/861.\347\277\273\350\275\254\347\237\251\351\230\265\345\220\216\347\232\204\345\276\227\345\210\206.py" rename to "leetcode_Python/861.\347\277\273\350\275\254\347\237\251\351\230\265\345\220\216\347\232\204\345\276\227\345\210\206.py" index 3d564be..ad123f2 100644 --- "a/leetcode/861.\347\277\273\350\275\254\347\237\251\351\230\265\345\220\216\347\232\204\345\276\227\345\210\206.py" +++ "b/leetcode_Python/861.\347\277\273\350\275\254\347\237\251\351\230\265\345\220\216\347\232\204\345\276\227\345\210\206.py" @@ -1,21 +1,21 @@ -# 使第一列全为1,其他列1要比0多 -class Solution(object): - def matrixScore(self, A): - res, m, n = 0, len(A), len(A[0]) - for i in range(m): - if A[i][0] == 0: - for j in range(n): - if A[i][j] == 0: - A[i][j] = 1 - else: - A[i][j] = 0 - res = m * pow(2, n-1) - for j in range(1, n): - count = 0 - for i in range(m): - if A[i][j] == 1: - count += 1 - if count <= m/2: - count = m - count - res += count * pow(2, n-1-j) +# 使第一列全为1,其他列1要比0多 +class Solution(object): + def matrixScore(self, A): + res, m, n = 0, len(A), len(A[0]) + for i in range(m): + if A[i][0] == 0: + for j in range(n): + if A[i][j] == 0: + A[i][j] = 1 + else: + A[i][j] = 0 + res = m * pow(2, n-1) + for j in range(1, n): + count = 0 + for i in range(m): + if A[i][j] == 1: + count += 1 + if count <= m/2: + count = m - count + res += count * pow(2, n-1-j) return res \ No newline at end of file diff --git "a/leetcode/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272K\347\232\204\347\273\223\347\202\271.py" "b/leetcode_Python/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272K\347\232\204\347\273\223\347\202\271.py" similarity index 97% rename from "leetcode/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272K\347\232\204\347\273\223\347\202\271.py" rename to "leetcode_Python/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272K\347\232\204\347\273\223\347\202\271.py" index 0c26a8c..9bb3381 100644 --- "a/leetcode/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272K\347\232\204\347\273\223\347\202\271.py" +++ "b/leetcode_Python/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272K\347\232\204\347\273\223\347\202\271.py" @@ -1,22 +1,22 @@ -class Solution(object): - def distanceK(self, root, target, K): - # 字典的值类型是列表 - con = collections.defaultdict(list) - - def connect(parent, child): - if parent and child: - con[parent.val].append(child.val) - con[child.val].append(parent.val) - if child.left: - connect(child, child.left) - if child.right: - connect(child, child.right) - - connect(None, root) - res = [target.val] - visited = set(res) - for _ in range(K): - res = [y for x in res for y in con[x] if y not in visited] - # 合并 - visited |= set(res) +class Solution(object): + def distanceK(self, root, target, K): + # 字典的值类型是列表 + con = collections.defaultdict(list) + + def connect(parent, child): + if parent and child: + con[parent.val].append(child.val) + con[child.val].append(parent.val) + if child.left: + connect(child, child.left) + if child.right: + connect(child, child.right) + + connect(None, root) + res = [target.val] + visited = set(res) + for _ in range(K): + res = [y for x in res for y in con[x] if y not in visited] + # 合并 + visited |= set(res) return res \ No newline at end of file diff --git "a/leetcode/865.\345\205\267\346\234\211\346\211\200\346\234\211\346\234\200\346\267\261\347\273\223\347\202\271\347\232\204\346\234\200\345\260\217\345\255\220\346\240\221.py" "b/leetcode_Python/865.\345\205\267\346\234\211\346\211\200\346\234\211\346\234\200\346\267\261\347\273\223\347\202\271\347\232\204\346\234\200\345\260\217\345\255\220\346\240\221.py" similarity index 97% rename from "leetcode/865.\345\205\267\346\234\211\346\211\200\346\234\211\346\234\200\346\267\261\347\273\223\347\202\271\347\232\204\346\234\200\345\260\217\345\255\220\346\240\221.py" rename to "leetcode_Python/865.\345\205\267\346\234\211\346\211\200\346\234\211\346\234\200\346\267\261\347\273\223\347\202\271\347\232\204\346\234\200\345\260\217\345\255\220\346\240\221.py" index c3d2ff1..3a8c740 100644 --- "a/leetcode/865.\345\205\267\346\234\211\346\211\200\346\234\211\346\234\200\346\267\261\347\273\223\347\202\271\347\232\204\346\234\200\345\260\217\345\255\220\346\240\221.py" +++ "b/leetcode_Python/865.\345\205\267\346\234\211\346\211\200\346\234\211\346\234\200\346\267\261\347\273\223\347\202\271\347\232\204\346\234\200\345\260\217\345\255\220\346\240\221.py" @@ -1,15 +1,15 @@ -class Solution(object): - def subtreeWithAllDeepest(self, root): - # 判断左右子树深度是否相同,若相同则根结点为所求 - res = self.depth(root.left) - self.depth(root.right) - if res == 0: - return root - elif res > 0: - return self.subtreeWithAllDeepest(root.left) - else: - return self.subtreeWithAllDeepest(root.right) - # 求树的深度 - def depth(self, root): - if not root: - return 0 +class Solution(object): + def subtreeWithAllDeepest(self, root): + # 判断左右子树深度是否相同,若相同则根结点为所求 + res = self.depth(root.left) - self.depth(root.right) + if res == 0: + return root + elif res > 0: + return self.subtreeWithAllDeepest(root.left) + else: + return self.subtreeWithAllDeepest(root.right) + # 求树的深度 + def depth(self, root): + if not root: + return 0 return 1 + max(self.depth(root.left), self.depth(root.right)) \ No newline at end of file diff --git "a/leetcode/867.\350\275\254\347\275\256\347\237\251\351\230\265.py" "b/leetcode_Python/867.\350\275\254\347\275\256\347\237\251\351\230\265.py" similarity index 96% rename from "leetcode/867.\350\275\254\347\275\256\347\237\251\351\230\265.py" rename to "leetcode_Python/867.\350\275\254\347\275\256\347\237\251\351\230\265.py" index 101a959..a9af084 100644 --- "a/leetcode/867.\350\275\254\347\275\256\347\237\251\351\230\265.py" +++ "b/leetcode_Python/867.\350\275\254\347\275\256\347\237\251\351\230\265.py" @@ -1,15 +1,15 @@ -# 先初始化结果矩阵的行列,再将值代入 -class Solution(object): - def transpose(self, A): - row = len(A) - col = len(A[0]) if row else 0 - res = [[0]*row for j in range(col)] - for i in range(row): - for j in range(col): - res[j][i] = A[i][j] - return res - -# *A代表解压缩 -class Solution(object): - def transpose(self, A): +# 先初始化结果矩阵的行列,再将值代入 +class Solution(object): + def transpose(self, A): + row = len(A) + col = len(A[0]) if row else 0 + res = [[0]*row for j in range(col)] + for i in range(row): + for j in range(col): + res[j][i] = A[i][j] + return res + +# *A代表解压缩 +class Solution(object): + def transpose(self, A): return [i for i in zip(*A)] \ No newline at end of file diff --git "a/leetcode/868.\344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.py" "b/leetcode_Python/868.\344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.py" similarity index 96% rename from "leetcode/868.\344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.py" rename to "leetcode_Python/868.\344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.py" index 08c3f2f..3fa5037 100644 --- "a/leetcode/868.\344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.py" +++ "b/leetcode_Python/868.\344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.py" @@ -1,14 +1,14 @@ -# 边遍历边统计每个间距的长度,更新最大间距 -class Solution(object): - def binaryGap(self, N): - n = bin(N)[2:] - res, count, i = 0, 1, 1 - while i < len(n): - if n[i] == '1': - res = max(res, count) - count = 1 - i += 1 - else: - count += 1 - i += 1 +# 边遍历边统计每个间距的长度,更新最大间距 +class Solution(object): + def binaryGap(self, N): + n = bin(N)[2:] + res, count, i = 0, 1, 1 + while i < len(n): + if n[i] == '1': + res = max(res, count) + count = 1 + i += 1 + else: + count += 1 + i += 1 return res \ No newline at end of file diff --git "a/leetcode/870.\344\274\230\345\212\277\346\264\227\347\211\214.py" "b/leetcode_Python/870.\344\274\230\345\212\277\346\264\227\347\211\214.py" similarity index 97% rename from "leetcode/870.\344\274\230\345\212\277\346\264\227\347\211\214.py" rename to "leetcode_Python/870.\344\274\230\345\212\277\346\264\227\347\211\214.py" index e74e665..1a3bc69 100644 --- "a/leetcode/870.\344\274\230\345\212\277\346\264\227\347\211\214.py" +++ "b/leetcode_Python/870.\344\274\230\345\212\277\346\264\227\347\211\214.py" @@ -1,19 +1,19 @@ -class Solution(object): - def advantageCount(self, A, B): - n = len(B) - A.sort() - # 记录元素的值和索引 - B = [(B[i], i) for i in range(n)] - B.sort() - # 使用左右指针指向B的左右两端 - l, r, k, res = 0, n-1, 0, [0]*n - for a in A: - # A的元素大于B的元素,则将A的元素放到B的元素对应的索引位置上 - if a > B[l][0]: - res[B[l][1]] = a - l += 1 - # 否则放到B最后一个元素对应的索引位置上 - else: - res[B[r][1]] = a - r -= 1 +class Solution(object): + def advantageCount(self, A, B): + n = len(B) + A.sort() + # 记录元素的值和索引 + B = [(B[i], i) for i in range(n)] + B.sort() + # 使用左右指针指向B的左右两端 + l, r, k, res = 0, n-1, 0, [0]*n + for a in A: + # A的元素大于B的元素,则将A的元素放到B的元素对应的索引位置上 + if a > B[l][0]: + res[B[l][1]] = a + l += 1 + # 否则放到B最后一个元素对应的索引位置上 + else: + res[B[r][1]] = a + r -= 1 return res \ No newline at end of file diff --git "a/leetcode/872.\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" "b/leetcode_Python/872.\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" similarity index 96% rename from "leetcode/872.\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" rename to "leetcode_Python/872.\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" index e353e0a..70fb7f6 100644 --- "a/leetcode/872.\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" +++ "b/leetcode_Python/872.\345\217\266\345\255\220\347\233\270\344\274\274\347\232\204\346\240\221.py" @@ -1,12 +1,12 @@ -# 获取叶值序列进行比较 -class Solution(object): - def leafSimilar(self, root1, root2): - def findLeaf(root): - if not root: - return [] - if not root.left and not root.right: - return [root.val] - return findLeaf(root.left) + findLeaf(root.right) - - return findLeaf(root1) == findLeaf(root2) - +# 获取叶值序列进行比较 +class Solution(object): + def leafSimilar(self, root1, root2): + def findLeaf(root): + if not root: + return [] + if not root.left and not root.right: + return [root.val] + return findLeaf(root.left) + findLeaf(root.right) + + return findLeaf(root1) == findLeaf(root2) + diff --git "a/leetcode/876.\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" "b/leetcode_Python/876.\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" similarity index 97% rename from "leetcode/876.\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" rename to "leetcode_Python/876.\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" index 6e49b84..00f25fb 100644 --- "a/leetcode/876.\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" +++ "b/leetcode_Python/876.\351\223\276\350\241\250\347\232\204\344\270\255\351\227\264\347\273\223\347\202\271.py" @@ -1,17 +1,17 @@ -# 方法一:用数组存放结点值,返回中间结点后面的值 -class Solution(object): - def middleNode(self, head): - res = [] - while head: - res.append(head.val) - head = head.next - return res[len(res)/2:] - -# 方法二:快的比慢的快一倍,当快的到底时,慢的刚好在中间 -class Solution(object): - def middleNode(self, head): - fast = slow = head - while fast and fast.next: - slow = slow.next - fast = fast.next.next +# 方法一:用数组存放结点值,返回中间结点后面的值 +class Solution(object): + def middleNode(self, head): + res = [] + while head: + res.append(head.val) + head = head.next + return res[len(res)/2:] + +# 方法二:快的比慢的快一倍,当快的到底时,慢的刚好在中间 +class Solution(object): + def middleNode(self, head): + fast = slow = head + while fast and fast.next: + slow = slow.next + fast = fast.next.next return slow \ No newline at end of file diff --git "a/leetcode/877.\347\237\263\345\255\220\346\270\270\346\210\217.py" "b/leetcode_Python/877.\347\237\263\345\255\220\346\270\270\346\210\217.py" similarity index 98% rename from "leetcode/877.\347\237\263\345\255\220\346\270\270\346\210\217.py" rename to "leetcode_Python/877.\347\237\263\345\255\220\346\270\270\346\210\217.py" index 49fee7e..fc6f083 100644 --- "a/leetcode/877.\347\237\263\345\255\220\346\270\270\346\210\217.py" +++ "b/leetcode_Python/877.\347\237\263\345\255\220\346\270\270\346\210\217.py" @@ -1,21 +1,21 @@ -# dp[i][j]:表示在piles中下标i至下标j之间的玩家1比玩家2多拿的石子数。dp[i][j]>0 表示玩家1赢 -# 子问题:dp[i+1][j]和dp[i][j-1] -# 初始状态:dp的初始状态是i=j即只有一个石子堆,由于玩家1先拿,则dp[i][j]=piles[i] -# 状态方程:dp[i][j] = max(piles[i] - dp[i+1][j], piles[j] - dp[i][j-1]) -# 状态方程理解:由于在有限石子堆中双方都要取最优,当前玩家1取piles[i]或piles[j]时,则上一步反过来代表玩家2取到最优即dp[i+1][j]或dp[i][j-1],故要相减 -class Solution(object): - def stoneGame(self, piles): - n = len(piles) - dp = [[0]*n for _ in range(n)] - # 初始化只有一个石头堆的情况 - for i in range(n): - dp[i][i] = piles[i] - # 每增加一个石头堆,则计算当前石头堆两个到n个的情况 - for i in range(n-2, -1, -1): - for j in range(i+1, n): - dp[i][j] = max(piles[i] - dp[i+1][j], piles[j] - dp[i][j-1]) - return dp[0][-1] > 0 -# 5 1 4 1 -# 0 4 1 4 -# 0 0 3 2 -# 0 0 0 5 +# dp[i][j]:表示在piles中下标i至下标j之间的玩家1比玩家2多拿的石子数。dp[i][j]>0 表示玩家1赢 +# 子问题:dp[i+1][j]和dp[i][j-1] +# 初始状态:dp的初始状态是i=j即只有一个石子堆,由于玩家1先拿,则dp[i][j]=piles[i] +# 状态方程:dp[i][j] = max(piles[i] - dp[i+1][j], piles[j] - dp[i][j-1]) +# 状态方程理解:由于在有限石子堆中双方都要取最优,当前玩家1取piles[i]或piles[j]时,则上一步反过来代表玩家2取到最优即dp[i+1][j]或dp[i][j-1],故要相减 +class Solution(object): + def stoneGame(self, piles): + n = len(piles) + dp = [[0]*n for _ in range(n)] + # 初始化只有一个石头堆的情况 + for i in range(n): + dp[i][i] = piles[i] + # 每增加一个石头堆,则计算当前石头堆两个到n个的情况 + for i in range(n-2, -1, -1): + for j in range(i+1, n): + dp[i][j] = max(piles[i] - dp[i+1][j], piles[j] - dp[i][j-1]) + return dp[0][-1] > 0 +# 5 1 4 1 +# 0 4 1 4 +# 0 0 3 2 +# 0 0 0 5 diff --git "a/leetcode/881.\346\225\221\347\224\237\350\211\207.py" "b/leetcode_Python/881.\346\225\221\347\224\237\350\211\207.py" similarity index 97% rename from "leetcode/881.\346\225\221\347\224\237\350\211\207.py" rename to "leetcode_Python/881.\346\225\221\347\224\237\350\211\207.py" index f9137da..1a31dc4 100644 --- "a/leetcode/881.\346\225\221\347\224\237\350\211\207.py" +++ "b/leetcode_Python/881.\346\225\221\347\224\237\350\211\207.py" @@ -1,11 +1,11 @@ -# 最多每个人需要一艘船,若最重和最轻若能组合则少一艘船 -class Solution(object): - def numRescueBoats(self, people, limit): - l, r, res = 0, len(people)-1, len(people) - people.sort() - while l < r: - if people[l] + people[r] <= limit: - res -= 1 - l += 1 - r -= 1 +# 最多每个人需要一艘船,若最重和最轻若能组合则少一艘船 +class Solution(object): + def numRescueBoats(self, people, limit): + l, r, res = 0, len(people)-1, len(people) + people.sort() + while l < r: + if people[l] + people[r] <= limit: + res -= 1 + l += 1 + r -= 1 return res \ No newline at end of file diff --git "a/leetcode/884.\344\270\244\345\217\245\350\257\235\344\270\255\347\232\204\344\270\215\345\270\270\350\247\201\345\215\225\350\257\215.py" "b/leetcode_Python/884.\344\270\244\345\217\245\350\257\235\344\270\255\347\232\204\344\270\215\345\270\270\350\247\201\345\215\225\350\257\215.py" similarity index 98% rename from "leetcode/884.\344\270\244\345\217\245\350\257\235\344\270\255\347\232\204\344\270\215\345\270\270\350\247\201\345\215\225\350\257\215.py" rename to "leetcode_Python/884.\344\270\244\345\217\245\350\257\235\344\270\255\347\232\204\344\270\215\345\270\270\350\247\201\345\215\225\350\257\215.py" index 4e6ae48..6cfbdcd 100644 --- "a/leetcode/884.\344\270\244\345\217\245\350\257\235\344\270\255\347\232\204\344\270\215\345\270\270\350\247\201\345\215\225\350\257\215.py" +++ "b/leetcode_Python/884.\344\270\244\345\217\245\350\257\235\344\270\255\347\232\204\344\270\215\345\270\270\350\247\201\345\215\225\350\257\215.py" @@ -1,6 +1,6 @@ -# 统计两个句子中出现次数为1的单词 -class Solution(object): - def uncommonFromSentences(self, A, B): - words = A.split() + B.split() - d = collections.Counter(words) +# 统计两个句子中出现次数为1的单词 +class Solution(object): + def uncommonFromSentences(self, A, B): + words = A.split() + B.split() + d = collections.Counter(words) return [word for word in words if d[word]==1] \ No newline at end of file diff --git "a/leetcode/888.\345\205\254\345\271\263\347\232\204\347\263\226\346\236\234\344\272\244\346\215\242.py" "b/leetcode_Python/888.\345\205\254\345\271\263\347\232\204\347\263\226\346\236\234\344\272\244\346\215\242.py" similarity index 98% rename from "leetcode/888.\345\205\254\345\271\263\347\232\204\347\263\226\346\236\234\344\272\244\346\215\242.py" rename to "leetcode_Python/888.\345\205\254\345\271\263\347\232\204\347\263\226\346\236\234\344\272\244\346\215\242.py" index a7d1dc0..b1383ba 100644 --- "a/leetcode/888.\345\205\254\345\271\263\347\232\204\347\263\226\346\236\234\344\272\244\346\215\242.py" +++ "b/leetcode_Python/888.\345\205\254\345\271\263\347\232\204\347\263\226\346\236\234\344\272\244\346\215\242.py" @@ -1,8 +1,8 @@ -# 先分别求两数组的和,再求总和之差的一半,得到两数组分别需要增减的值。再遍历数组,得到符合增减条件的两个数 -class Solution(object): - def fairCandySwap(self, A, B): - sumA, sumB, setB = sum(A), sum(B), set(B) - for a in A: - b = (sumB-sumA)/2 + a - if b in setB: +# 先分别求两数组的和,再求总和之差的一半,得到两数组分别需要增减的值。再遍历数组,得到符合增减条件的两个数 +class Solution(object): + def fairCandySwap(self, A, B): + sumA, sumB, setB = sum(A), sum(B), set(B) + for a in A: + b = (sumB-sumA)/2 + a + if b in setB: return [a, b] \ No newline at end of file diff --git "a/leetcode/889.\346\240\271\346\215\256\345\211\215\345\272\217\345\222\214\345\220\216\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/889.\346\240\271\346\215\256\345\211\215\345\272\217\345\222\214\345\220\216\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/889.\346\240\271\346\215\256\345\211\215\345\272\217\345\222\214\345\220\216\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/889.\346\240\271\346\215\256\345\211\215\345\272\217\345\222\214\345\220\216\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" index 0cdf08f..1466bbe 100644 --- "a/leetcode/889.\346\240\271\346\215\256\345\211\215\345\272\217\345\222\214\345\220\216\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/889.\346\240\271\346\215\256\345\211\215\345\272\217\345\222\214\345\220\216\345\272\217\351\201\215\345\216\206\346\236\204\351\200\240\344\272\214\345\217\211\346\240\221.py" @@ -1,19 +1,19 @@ -# 前序遍历的第一个元素,后续遍历的最后一个元素,是根节点 -# 从前序看 2 是左树的根节点,我们需要知道左树的长度,从后序找到2的位置,则4,5,2 是整个左树 -class Solution(object): - def constructFromPrePost(self, pre, post): - root = TreeNode(pre[0]) - pre = pre[1:] - post = post[:-1] - len_left = 0 - for i in post: - if i == pre[0]: - len_left += 1 - break - else: - len_left += 1 - if len_left > 0: - root.left = self.constructFromPrePost(pre[:len_left], post[:len_left]) - if len(pre) - len_left > 0: - root.right = self.constructFromPrePost(pre[len_left:], post[len_left:]) +# 前序遍历的第一个元素,后续遍历的最后一个元素,是根节点 +# 从前序看 2 是左树的根节点,我们需要知道左树的长度,从后序找到2的位置,则4,5,2 是整个左树 +class Solution(object): + def constructFromPrePost(self, pre, post): + root = TreeNode(pre[0]) + pre = pre[1:] + post = post[:-1] + len_left = 0 + for i in post: + if i == pre[0]: + len_left += 1 + break + else: + len_left += 1 + if len_left > 0: + root.left = self.constructFromPrePost(pre[:len_left], post[:len_left]) + if len(pre) - len_left > 0: + root.right = self.constructFromPrePost(pre[len_left:], post[len_left:]) return root \ No newline at end of file diff --git "a/leetcode/890.\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\346\250\241\345\274\217.py" "b/leetcode_Python/890.\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\346\250\241\345\274\217.py" similarity index 98% rename from "leetcode/890.\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\346\250\241\345\274\217.py" rename to "leetcode_Python/890.\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\346\250\241\345\274\217.py" index 49c626c..a27f417 100644 --- "a/leetcode/890.\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\346\250\241\345\274\217.py" +++ "b/leetcode_Python/890.\346\237\245\346\211\276\345\222\214\346\233\277\346\215\242\346\250\241\345\274\217.py" @@ -1,9 +1,9 @@ -# 将单词、模板、两者组合成的元组去重,判断长度是否相等,以此判断是否匹配 -class Solution(object): - def findAndReplacePattern(self, words, pattern): - return [word for word in words if self.isMatch(word, pattern)] - - def isMatch(self, word, pattern): - if len(word) != len(pattern): - return False +# 将单词、模板、两者组合成的元组去重,判断长度是否相等,以此判断是否匹配 +class Solution(object): + def findAndReplacePattern(self, words, pattern): + return [word for word in words if self.isMatch(word, pattern)] + + def isMatch(self, word, pattern): + if len(word) != len(pattern): + return False return len(set(word)) == len(set(pattern)) == len(set(zip(word, pattern))) \ No newline at end of file diff --git "a/leetcode/893.\347\211\271\346\256\212\347\255\211\344\273\267\345\255\227\347\254\246\344\270\262\347\273\204.py" "b/leetcode_Python/893.\347\211\271\346\256\212\347\255\211\344\273\267\345\255\227\347\254\246\344\270\262\347\273\204.py" similarity index 96% rename from "leetcode/893.\347\211\271\346\256\212\347\255\211\344\273\267\345\255\227\347\254\246\344\270\262\347\273\204.py" rename to "leetcode_Python/893.\347\211\271\346\256\212\347\255\211\344\273\267\345\255\227\347\254\246\344\270\262\347\273\204.py" index c0e8b96..2ae92f7 100644 --- "a/leetcode/893.\347\211\271\346\256\212\347\255\211\344\273\267\345\255\227\347\254\246\344\270\262\347\273\204.py" +++ "b/leetcode_Python/893.\347\211\271\346\256\212\347\255\211\344\273\267\345\255\227\347\254\246\344\270\262\347\273\204.py" @@ -1,23 +1,23 @@ -# 使用字典 -class Solution(object): - def numSpecialEquivGroups(self, A): - d = {} - for s in A: - odd = [s[i] for i in range(0, len(s), 2)] - even = [s[i] for i in range(1, len(s), 2)] - odd.sort() - even.sort() - d[''.join(odd + even)] = 1 - return len(d) - -# 使用集合 -class Solution(object): - def numSpecialEquivGroups(self, A): - res = set() - for s in A: - odd = [s[i] for i in range(0, len(s), 2)] - even = [s[i] for i in range(1, len(s), 2)] - odd.sort() - even.sort() - res.add(''.join(odd + even)) +# 使用字典 +class Solution(object): + def numSpecialEquivGroups(self, A): + d = {} + for s in A: + odd = [s[i] for i in range(0, len(s), 2)] + even = [s[i] for i in range(1, len(s), 2)] + odd.sort() + even.sort() + d[''.join(odd + even)] = 1 + return len(d) + +# 使用集合 +class Solution(object): + def numSpecialEquivGroups(self, A): + res = set() + for s in A: + odd = [s[i] for i in range(0, len(s), 2)] + even = [s[i] for i in range(1, len(s), 2)] + odd.sort() + even.sort() + res.add(''.join(odd + even)) return len(res) \ No newline at end of file diff --git "a/leetcode/894.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\346\273\241\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/894.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\346\273\241\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/894.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\346\273\241\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/894.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\346\273\241\344\272\214\345\217\211\346\240\221.py" index 667996b..c720d67 100644 --- "a/leetcode/894.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\346\273\241\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/894.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\346\273\241\344\272\214\345\217\211\346\240\221.py" @@ -1,31 +1,31 @@ -class Solution(object): - def allPossibleFBT(self, N): - N -= 1 - if N == 0: - return [TreeNode(0)] - res = [] - for i in range(1, N, 2): - for left in self.allPossibleFBT(i): - for right in self.allPossibleFBT(N - i): - node = TreeNode(0) - node.left = left - node.right = right - res.append(node) - return res - -##################### 递归思路 ####################### -# 方法作用极简化:先判断1个结点和3个结点的情况 -# 方法作用描述:参数给一个结点数N,将N个结点组合成树,然后返回根结点 -# 递归:由于左右子树需要同样操作,使用递归。 -# 由于左右子树结点数目、类型可变,使用两重for循环 -class Solution(object): - def allPossibleFBT(self, N): - N -= 1 - if N == 0: - return [TreeNode(0)] - res = [] - node = TreeNode(0) - node.left = TreeNode(0) - node.right = TreeNode(0) - res.append(node) +class Solution(object): + def allPossibleFBT(self, N): + N -= 1 + if N == 0: + return [TreeNode(0)] + res = [] + for i in range(1, N, 2): + for left in self.allPossibleFBT(i): + for right in self.allPossibleFBT(N - i): + node = TreeNode(0) + node.left = left + node.right = right + res.append(node) + return res + +##################### 递归思路 ####################### +# 方法作用极简化:先判断1个结点和3个结点的情况 +# 方法作用描述:参数给一个结点数N,将N个结点组合成树,然后返回根结点 +# 递归:由于左右子树需要同样操作,使用递归。 +# 由于左右子树结点数目、类型可变,使用两重for循环 +class Solution(object): + def allPossibleFBT(self, N): + N -= 1 + if N == 0: + return [TreeNode(0)] + res = [] + node = TreeNode(0) + node.left = TreeNode(0) + node.right = TreeNode(0) + res.append(node) return res \ No newline at end of file diff --git "a/leetcode/896.\345\215\225\350\260\203\346\225\260\345\210\227.py" "b/leetcode_Python/896.\345\215\225\350\260\203\346\225\260\345\210\227.py" similarity index 97% rename from "leetcode/896.\345\215\225\350\260\203\346\225\260\345\210\227.py" rename to "leetcode_Python/896.\345\215\225\350\260\203\346\225\260\345\210\227.py" index 4e9255b..1a6d32d 100644 --- "a/leetcode/896.\345\215\225\350\260\203\346\225\260\345\210\227.py" +++ "b/leetcode_Python/896.\345\215\225\350\260\203\346\225\260\345\210\227.py" @@ -1,17 +1,17 @@ -# 方法一:排序,比较与正反排序结果是否相等 -class Solution(object): - def isMonotonic(self, A): - if A == sorted(A) or A == sorted(A)[::-1]: - return True - return False - -# 方法二:设置标志,遍历数组,不满足条件者设为False,返回两者其一 -class Solution(object): - def isMonotonic(self, A): - up = down = True - for i in range(len(A)-1): - if A[i] > A[i+1]: - up = False - if A[i] < A[i+1]: - down = False +# 方法一:排序,比较与正反排序结果是否相等 +class Solution(object): + def isMonotonic(self, A): + if A == sorted(A) or A == sorted(A)[::-1]: + return True + return False + +# 方法二:设置标志,遍历数组,不满足条件者设为False,返回两者其一 +class Solution(object): + def isMonotonic(self, A): + up = down = True + for i in range(len(A)-1): + if A[i] > A[i+1]: + up = False + if A[i] < A[i+1]: + down = False return up or down \ No newline at end of file diff --git "a/leetcode/897.\351\200\222\345\242\236\351\241\272\345\272\217\346\237\245\346\211\276\346\240\221.py" "b/leetcode_Python/897.\351\200\222\345\242\236\351\241\272\345\272\217\346\237\245\346\211\276\346\240\221.py" similarity index 96% rename from "leetcode/897.\351\200\222\345\242\236\351\241\272\345\272\217\346\237\245\346\211\276\346\240\221.py" rename to "leetcode_Python/897.\351\200\222\345\242\236\351\241\272\345\272\217\346\237\245\346\211\276\346\240\221.py" index f8b2980..1c9d9e1 100644 --- "a/leetcode/897.\351\200\222\345\242\236\351\241\272\345\272\217\346\237\245\346\211\276\346\240\221.py" +++ "b/leetcode_Python/897.\351\200\222\345\242\236\351\241\272\345\272\217\346\237\245\346\211\276\346\240\221.py" @@ -1,20 +1,20 @@ -# 中序遍历获取结点值数组,依次连接结点为右孩子 -class Solution(object): - def increasingBST(self, root): - if not root: - return [] - - def inorder(root): - if root: - inorder(root.left) - res.append(root.val) - inorder(root.right) - - res = [] - inorder(root) - head1 = TreeNode(res[0]) - head2 = head1 - for v in res[1:]: - head2.right = TreeNode(v) - head2 = head2.right +# 中序遍历获取结点值数组,依次连接结点为右孩子 +class Solution(object): + def increasingBST(self, root): + if not root: + return [] + + def inorder(root): + if root: + inorder(root.left) + res.append(root.val) + inorder(root.right) + + res = [] + inorder(root) + head1 = TreeNode(res[0]) + head2 = head1 + for v in res[1:]: + head2.right = TreeNode(v) + head2 = head2.right return head1 \ No newline at end of file diff --git "a/leetcode/905.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204.py" "b/leetcode_Python/905.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204.py" similarity index 96% rename from "leetcode/905.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204.py" rename to "leetcode_Python/905.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204.py" index 41a72fd..3d9a78c 100644 --- "a/leetcode/905.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204.py" +++ "b/leetcode_Python/905.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204.py" @@ -1,9 +1,9 @@ -class Solution(object): - def sortArrayByParity(self, A): - even, odd = [], [] - for a in A: - if a%2 == 0: - even.append(a) - else: - odd.append(a) +class Solution(object): + def sortArrayByParity(self, A): + even, odd = [], [] + for a in A: + if a%2 == 0: + even.append(a) + else: + odd.append(a) return even + odd \ No newline at end of file diff --git "a/leetcode/908.\346\234\200\345\260\217\345\267\256\345\200\274 I.py" "b/leetcode_Python/908.\346\234\200\345\260\217\345\267\256\345\200\274 I.py" similarity index 98% rename from "leetcode/908.\346\234\200\345\260\217\345\267\256\345\200\274 I.py" rename to "leetcode_Python/908.\346\234\200\345\260\217\345\267\256\345\200\274 I.py" index b4d0b38..5b8db7a 100644 --- "a/leetcode/908.\346\234\200\345\260\217\345\267\256\345\200\274 I.py" +++ "b/leetcode_Python/908.\346\234\200\345\260\217\345\267\256\345\200\274 I.py" @@ -1,4 +1,4 @@ -# 添加新元素后最小差缩小了2k,若减去2k结果为正则为最终答案,否则为0 -class Solution(object): - def smallestRangeI(self, A, K): +# 添加新元素后最小差缩小了2k,若减去2k结果为正则为最终答案,否则为0 +class Solution(object): + def smallestRangeI(self, A, K): return max(max(A) - min(A) - 2*K, 0) \ No newline at end of file diff --git "a/leetcode/910.\346\234\200\345\260\217\345\267\256\345\200\274 II.py" "b/leetcode_Python/910.\346\234\200\345\260\217\345\267\256\345\200\274 II.py" similarity index 97% rename from "leetcode/910.\346\234\200\345\260\217\345\267\256\345\200\274 II.py" rename to "leetcode_Python/910.\346\234\200\345\260\217\345\267\256\345\200\274 II.py" index 6159896..92d1544 100644 --- "a/leetcode/910.\346\234\200\345\260\217\345\267\256\345\200\274 II.py" +++ "b/leetcode_Python/910.\346\234\200\345\260\217\345\267\256\345\200\274 II.py" @@ -1,14 +1,14 @@ -# 数组排序后分成两部分,前一部分全部加K,后一部分全部减K -# 取出两部分的第一个元素的更小者,最后一个元素的更大者,得到变化后的数组的最大最小值 -class Solution(object): - def smallestRangeII(self, A, K): - n = len(A) - if n < 2: - return 0 - A.sort() - res = A[n-1] - A[0] - for i in range(1, n): - minu = min(A[0] + K, A[i] - K) - maxu = max(A[i-1] + K, A[n-1] - K) - res = min(res, maxu - minu) +# 数组排序后分成两部分,前一部分全部加K,后一部分全部减K +# 取出两部分的第一个元素的更小者,最后一个元素的更大者,得到变化后的数组的最大最小值 +class Solution(object): + def smallestRangeII(self, A, K): + n = len(A) + if n < 2: + return 0 + A.sort() + res = A[n-1] - A[0] + for i in range(1, n): + minu = min(A[0] + K, A[i] - K) + maxu = max(A[i-1] + K, A[n-1] - K) + res = min(res, maxu - minu) return res \ No newline at end of file diff --git "a/leetcode/914.\345\215\241\347\211\214\345\210\206\347\273\204.py" "b/leetcode_Python/914.\345\215\241\347\211\214\345\210\206\347\273\204.py" similarity index 97% rename from "leetcode/914.\345\215\241\347\211\214\345\210\206\347\273\204.py" rename to "leetcode_Python/914.\345\215\241\347\211\214\345\210\206\347\273\204.py" index 4f7f425..73e6b27 100644 --- "a/leetcode/914.\345\215\241\347\211\214\345\210\206\347\273\204.py" +++ "b/leetcode_Python/914.\345\215\241\347\211\214\345\210\206\347\273\204.py" @@ -1,17 +1,17 @@ -class Solution(object): - def hasGroupsSizeX(self, deck): - d = collections.Counter(deck) - min_v = min(d.values()) - # 元素最小次数小于2为False - if min_v < 2: - return False - # 求最大公约数 - def gcd(a, b): - if a % b == 0: - return b - return gcd(b, a%b) - # 求每个元素的次数与最小次数的最大公约数,小于2为False - for v in d.values(): - if gcd(v, min_v) < 2: - return False +class Solution(object): + def hasGroupsSizeX(self, deck): + d = collections.Counter(deck) + min_v = min(d.values()) + # 元素最小次数小于2为False + if min_v < 2: + return False + # 求最大公约数 + def gcd(a, b): + if a % b == 0: + return b + return gcd(b, a%b) + # 求每个元素的次数与最小次数的最大公约数,小于2为False + for v in d.values(): + if gcd(v, min_v) < 2: + return False return True \ No newline at end of file diff --git "a/leetcode/917.\344\273\205\344\273\205\345\217\215\350\275\254\345\255\227\346\257\215.py" "b/leetcode_Python/917.\344\273\205\344\273\205\345\217\215\350\275\254\345\255\227\346\257\215.py" similarity index 97% rename from "leetcode/917.\344\273\205\344\273\205\345\217\215\350\275\254\345\255\227\346\257\215.py" rename to "leetcode_Python/917.\344\273\205\344\273\205\345\217\215\350\275\254\345\255\227\346\257\215.py" index 5d1b93f..4cfc591 100644 --- "a/leetcode/917.\344\273\205\344\273\205\345\217\215\350\275\254\345\255\227\346\257\215.py" +++ "b/leetcode_Python/917.\344\273\205\344\273\205\345\217\215\350\275\254\345\255\227\346\257\215.py" @@ -1,29 +1,29 @@ -# 方法一:分别提取出字母和其他字符,再将其他字符按原来的索引位置插入到反转后的字母数组中 -class Solution(object): - def reverseOnlyLetters(self, S): - other, res = [], [] - for i, s in enumerate(S): - if s.isalpha(): - res.append(s) - else: - other.append((i, s)) - res = res[::-1] - for i, s in other: - res.insert(i, s) - return ''.join(res) - -# 方法二:从头尾遍历元素,两个都是字母时交换元素的值 -class Solution(object): - def reverseOnlyLetters(self, S): - S = list(S) - l, r = 0, len(S)-1 - while l < r: - if not S[l].isalpha(): - l += 1 - elif not S[r].isalpha(): - r -= 1 - else: - S[l], S[r] = S[r], S[l] - l += 1 - r -= 1 +# 方法一:分别提取出字母和其他字符,再将其他字符按原来的索引位置插入到反转后的字母数组中 +class Solution(object): + def reverseOnlyLetters(self, S): + other, res = [], [] + for i, s in enumerate(S): + if s.isalpha(): + res.append(s) + else: + other.append((i, s)) + res = res[::-1] + for i, s in other: + res.insert(i, s) + return ''.join(res) + +# 方法二:从头尾遍历元素,两个都是字母时交换元素的值 +class Solution(object): + def reverseOnlyLetters(self, S): + S = list(S) + l, r = 0, len(S)-1 + while l < r: + if not S[l].isalpha(): + l += 1 + elif not S[r].isalpha(): + r -= 1 + else: + S[l], S[r] = S[r], S[l] + l += 1 + r -= 1 return ''.join(S) \ No newline at end of file diff --git "a/leetcode/921.\344\275\277\346\213\254\345\217\267\346\234\211\346\225\210\347\232\204\346\234\200\345\260\221\346\267\273\345\212\240.py" "b/leetcode_Python/921.\344\275\277\346\213\254\345\217\267\346\234\211\346\225\210\347\232\204\346\234\200\345\260\221\346\267\273\345\212\240.py" similarity index 97% rename from "leetcode/921.\344\275\277\346\213\254\345\217\267\346\234\211\346\225\210\347\232\204\346\234\200\345\260\221\346\267\273\345\212\240.py" rename to "leetcode_Python/921.\344\275\277\346\213\254\345\217\267\346\234\211\346\225\210\347\232\204\346\234\200\345\260\221\346\267\273\345\212\240.py" index fbc06c6..368ec53 100644 --- "a/leetcode/921.\344\275\277\346\213\254\345\217\267\346\234\211\346\225\210\347\232\204\346\234\200\345\260\221\346\267\273\345\212\240.py" +++ "b/leetcode_Python/921.\344\275\277\346\213\254\345\217\267\346\234\211\346\225\210\347\232\204\346\234\200\345\260\221\346\267\273\345\212\240.py" @@ -1,12 +1,12 @@ -# 最坏情况下需要添加次数等于字符串长度,利用栈存放左括号,当遇到右括号时栈中有左括号配对,则弹出一个左括号并且减少两次添加 -class Solution(object): - def minAddToMakeValid(self, S): - res = len(S) - stack = [] - for s in S: - if s == '(': - stack.append(s) - if s == ')' and stack: - stack.pop() - res -= 2 +# 最坏情况下需要添加次数等于字符串长度,利用栈存放左括号,当遇到右括号时栈中有左括号配对,则弹出一个左括号并且减少两次添加 +class Solution(object): + def minAddToMakeValid(self, S): + res = len(S) + stack = [] + for s in S: + if s == '(': + stack.append(s) + if s == ')' and stack: + stack.pop() + res -= 2 return res \ No newline at end of file diff --git "a/leetcode/922.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204II.py" "b/leetcode_Python/922.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204II.py" similarity index 96% rename from "leetcode/922.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204II.py" rename to "leetcode_Python/922.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204II.py" index 564428b..773249a 100644 --- "a/leetcode/922.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204II.py" +++ "b/leetcode_Python/922.\346\214\211\345\245\207\345\201\266\346\216\222\345\272\217\346\225\260\347\273\204II.py" @@ -1,19 +1,19 @@ -# 方法一:分别提取奇偶元素,再间隔插入原数组 -class Solution(object): - def sortArrayByParityII(self, A): - even, odd = [], [] - for i in A: - if i%2==0: - even.append(i) - else: - odd.append(i) - A[::2] = even - A[1::2] = odd - return A - -# 方法二:使用zip -class Solution(object): - def sortArrayByParityII(self, A): - even = [i for i in A if not i%2] - odd = [i for i in A if i%2] +# 方法一:分别提取奇偶元素,再间隔插入原数组 +class Solution(object): + def sortArrayByParityII(self, A): + even, odd = [], [] + for i in A: + if i%2==0: + even.append(i) + else: + odd.append(i) + A[::2] = even + A[1::2] = odd + return A + +# 方法二:使用zip +class Solution(object): + def sortArrayByParityII(self, A): + even = [i for i in A if not i%2] + odd = [i for i in A if i%2] return [i for z in zip(even, odd) for i in z] \ No newline at end of file diff --git "a/leetcode/925.\351\225\277\351\224\256\346\214\211\345\205\245.py" "b/leetcode_Python/925.\351\225\277\351\224\256\346\214\211\345\205\245.py" similarity index 97% rename from "leetcode/925.\351\225\277\351\224\256\346\214\211\345\205\245.py" rename to "leetcode_Python/925.\351\225\277\351\224\256\346\214\211\345\205\245.py" index 058ee58..5033746 100644 --- "a/leetcode/925.\351\225\277\351\224\256\346\214\211\345\205\245.py" +++ "b/leetcode_Python/925.\351\225\277\351\224\256\346\214\211\345\205\245.py" @@ -1,11 +1,11 @@ -# 在两个字符串长度范围内,用两个指针指向两个字符串的首部,若两个元素相同则两指针各前进一步,否则typed的指针前进一步 -class Solution(object): - def isLongPressedName(self, name, typed): - i = j = 0 - while i < len(name) and j < len(typed): - if name[i] == typed[j]: - i += 1 - j += 1 - else: - j += 1 +# 在两个字符串长度范围内,用两个指针指向两个字符串的首部,若两个元素相同则两指针各前进一步,否则typed的指针前进一步 +class Solution(object): + def isLongPressedName(self, name, typed): + i = j = 0 + while i < len(name) and j < len(typed): + if name[i] == typed[j]: + i += 1 + j += 1 + else: + j += 1 return i == len(name) \ No newline at end of file diff --git "a/leetcode/929.\347\213\254\347\211\271\347\232\204\347\224\265\345\255\220\351\202\256\344\273\266\345\234\260\345\235\200.py" "b/leetcode_Python/929.\347\213\254\347\211\271\347\232\204\347\224\265\345\255\220\351\202\256\344\273\266\345\234\260\345\235\200.py" similarity index 97% rename from "leetcode/929.\347\213\254\347\211\271\347\232\204\347\224\265\345\255\220\351\202\256\344\273\266\345\234\260\345\235\200.py" rename to "leetcode_Python/929.\347\213\254\347\211\271\347\232\204\347\224\265\345\255\220\351\202\256\344\273\266\345\234\260\345\235\200.py" index 0cae507..7b19326 100644 --- "a/leetcode/929.\347\213\254\347\211\271\347\232\204\347\224\265\345\255\220\351\202\256\344\273\266\345\234\260\345\235\200.py" +++ "b/leetcode_Python/929.\347\213\254\347\211\271\347\232\204\347\224\265\345\255\220\351\202\256\344\273\266\345\234\260\345\235\200.py" @@ -1,15 +1,15 @@ -# 字符串分割、提取、合并 -class Solution(object): - def numUniqueEmails(self, emails): - res = set() - for email in emails: - local, domain = email.split('@')[0], email.split('@')[1] - local = local.split('+')[0] - local = ''.join([i for i in local if i != '.']) - res.add(local + '@' + domain) - return len(res) - -# 一行代码 -class Solution(object): - def numUniqueEmails(self, emails): +# 字符串分割、提取、合并 +class Solution(object): + def numUniqueEmails(self, emails): + res = set() + for email in emails: + local, domain = email.split('@')[0], email.split('@')[1] + local = local.split('+')[0] + local = ''.join([i for i in local if i != '.']) + res.add(local + '@' + domain) + return len(res) + +# 一行代码 +class Solution(object): + def numUniqueEmails(self, emails): return len(set([email.split('@')[0].split('+')[0].replace('.', '') + '@' + email.split('@')[1] for email in emails])) \ No newline at end of file diff --git "a/leetcode/931.\344\270\213\351\231\215\350\267\257\345\276\204\346\234\200\345\260\217\345\222\214.py" "b/leetcode_Python/931.\344\270\213\351\231\215\350\267\257\345\276\204\346\234\200\345\260\217\345\222\214.py" similarity index 97% rename from "leetcode/931.\344\270\213\351\231\215\350\267\257\345\276\204\346\234\200\345\260\217\345\222\214.py" rename to "leetcode_Python/931.\344\270\213\351\231\215\350\267\257\345\276\204\346\234\200\345\260\217\345\222\214.py" index df24017..ca83445 100644 --- "a/leetcode/931.\344\270\213\351\231\215\350\267\257\345\276\204\346\234\200\345\260\217\345\222\214.py" +++ "b/leetcode_Python/931.\344\270\213\351\231\215\350\267\257\345\276\204\346\234\200\345\260\217\345\222\214.py" @@ -1,14 +1,14 @@ -# 动态规划,自顶向下,原地改动,A[i][j]记录当前位置最小路径和 -class Solution(object): - def minFallingPathSum(self, A): - for i in range(1, len(A)): - for j in range(len(A)): - if j == 0: - A[i][j] += min(A[i-1][j], A[i-1][j+1]) - elif j == len(A)-1: - A[i][j] += min(A[i-1][j], A[i-1][j-1]) - else: - A[i][j] += min(A[i-1][j], A[i-1][j+1], A[i-1][j-1]) - return min(A[-1]) - - +# 动态规划,自顶向下,原地改动,A[i][j]记录当前位置最小路径和 +class Solution(object): + def minFallingPathSum(self, A): + for i in range(1, len(A)): + for j in range(len(A)): + if j == 0: + A[i][j] += min(A[i-1][j], A[i-1][j+1]) + elif j == len(A)-1: + A[i][j] += min(A[i-1][j], A[i-1][j-1]) + else: + A[i][j] += min(A[i-1][j], A[i-1][j+1], A[i-1][j-1]) + return min(A[-1]) + + diff --git "a/leetcode/934.\346\234\200\347\237\255\347\232\204\346\241\245.py" "b/leetcode_Python/934.\346\234\200\347\237\255\347\232\204\346\241\245.py" similarity index 97% rename from "leetcode/934.\346\234\200\347\237\255\347\232\204\346\241\245.py" rename to "leetcode_Python/934.\346\234\200\347\237\255\347\232\204\346\241\245.py" index 9fc9a33..a919acd 100644 --- "a/leetcode/934.\346\234\200\347\237\255\347\232\204\346\241\245.py" +++ "b/leetcode_Python/934.\346\234\200\347\237\255\347\232\204\346\241\245.py" @@ -1,43 +1,43 @@ -class Solution(object): - def shortestBridge(self, A): - m, n = len(A), len(A[0]) - d = [(1, 0), (-1, 0), (0, 1), (0, -1)] - - # 深度优先搜索,将一片岛屿置为-1 - def dfs(x, y): - A[x][y] = -1 - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n and A[nx][ny] == 1: - dfs(nx, ny) - - # 找到一个1,将其所在的A岛屿置为-1 - flag = 0 - for i in range(m): - for j in range(n): - if A[i][j] == 1: - dfs(i, j) - flag = 1 - if flag: - break - if flag: - break - - # 将B岛屿每个位置添加到队列中 - q = [] - for i in range(m): - for j in range(n): - if A[i][j] == 1: - q.append((i, j, 0)) - - # 广度优先搜索,B岛屿中某个位置先到达A岛屿,则返回其路径长度 - while q: - x, y, r = q.pop(0) - for dx, dy in d: - nx, ny = x + dx, y + dy - if 0 <= nx < m and 0 <= ny < n: - if A[nx][ny] == 0: - A[nx][ny] = 1 - q.append((nx, ny, r + 1)) - if A[nx][ny] == -1: +class Solution(object): + def shortestBridge(self, A): + m, n = len(A), len(A[0]) + d = [(1, 0), (-1, 0), (0, 1), (0, -1)] + + # 深度优先搜索,将一片岛屿置为-1 + def dfs(x, y): + A[x][y] = -1 + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n and A[nx][ny] == 1: + dfs(nx, ny) + + # 找到一个1,将其所在的A岛屿置为-1 + flag = 0 + for i in range(m): + for j in range(n): + if A[i][j] == 1: + dfs(i, j) + flag = 1 + if flag: + break + if flag: + break + + # 将B岛屿每个位置添加到队列中 + q = [] + for i in range(m): + for j in range(n): + if A[i][j] == 1: + q.append((i, j, 0)) + + # 广度优先搜索,B岛屿中某个位置先到达A岛屿,则返回其路径长度 + while q: + x, y, r = q.pop(0) + for dx, dy in d: + nx, ny = x + dx, y + dy + if 0 <= nx < m and 0 <= ny < n: + if A[nx][ny] == 0: + A[nx][ny] = 1 + q.append((nx, ny, r + 1)) + if A[nx][ny] == -1: return r \ No newline at end of file diff --git "a/leetcode/937.\351\207\215\346\226\260\346\216\222\345\210\227\346\227\245\345\277\227\346\226\207\344\273\266.py" "b/leetcode_Python/937.\351\207\215\346\226\260\346\216\222\345\210\227\346\227\245\345\277\227\346\226\207\344\273\266.py" similarity index 97% rename from "leetcode/937.\351\207\215\346\226\260\346\216\222\345\210\227\346\227\245\345\277\227\346\226\207\344\273\266.py" rename to "leetcode_Python/937.\351\207\215\346\226\260\346\216\222\345\210\227\346\227\245\345\277\227\346\226\207\344\273\266.py" index 8360975..8860eda 100644 --- "a/leetcode/937.\351\207\215\346\226\260\346\216\222\345\210\227\346\227\245\345\277\227\346\226\207\344\273\266.py" +++ "b/leetcode_Python/937.\351\207\215\346\226\260\346\216\222\345\210\227\346\227\245\345\277\227\346\226\207\344\273\266.py" @@ -1,11 +1,11 @@ -# 将字母日志和数字日志分开,字母日志排序后,再组合在一起 -class Solution(object): - def reorderLogFiles(self, logs): - digit, letter = [], [] - for log in logs: - if log.split()[1].isdigit(): - digit.append(log) - else: - letter.append(log) - letter.sort(key=lambda x: x.split()[1:]) +# 将字母日志和数字日志分开,字母日志排序后,再组合在一起 +class Solution(object): + def reorderLogFiles(self, logs): + digit, letter = [], [] + for log in logs: + if log.split()[1].isdigit(): + digit.append(log) + else: + letter.append(log) + letter.sort(key=lambda x: x.split()[1:]) return letter + digit \ No newline at end of file diff --git "a/leetcode/938.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\350\214\203\345\233\264\345\222\214.py" "b/leetcode_Python/938.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\350\214\203\345\233\264\345\222\214.py" similarity index 97% rename from "leetcode/938.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\350\214\203\345\233\264\345\222\214.py" rename to "leetcode_Python/938.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\350\214\203\345\233\264\345\222\214.py" index 6d45645..61e26a0 100644 --- "a/leetcode/938.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\350\214\203\345\233\264\345\222\214.py" +++ "b/leetcode_Python/938.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\350\214\203\345\233\264\345\222\214.py" @@ -1,24 +1,24 @@ -# 中序遍历后将给定范围的值求和 -class Solution(object): - def rangeSumBST(self, root, L, R): - self.res = [] - def midOrder(root): - if root: - midOrder(root.left) - self.res.append(root.val) - midOrder(root.right) - midOrder(root) - return sum(self.res[self.res.index(L):self.res.index(R)+1]) - -# 遍历每个结点,若该值在范围内则累加 -class Solution2(object): - def rangeSumBST(self, root, L, R): - self.res = 0 - def addScope(root): - if root: - if L <= root.val <= R: - self.res += root.val - addScope(root.left) - addScope(root.right) - addScope(root) +# 中序遍历后将给定范围的值求和 +class Solution(object): + def rangeSumBST(self, root, L, R): + self.res = [] + def midOrder(root): + if root: + midOrder(root.left) + self.res.append(root.val) + midOrder(root.right) + midOrder(root) + return sum(self.res[self.res.index(L):self.res.index(R)+1]) + +# 遍历每个结点,若该值在范围内则累加 +class Solution2(object): + def rangeSumBST(self, root, L, R): + self.res = 0 + def addScope(root): + if root: + if L <= root.val <= R: + self.res += root.val + addScope(root.left) + addScope(root.right) + addScope(root) return self.res \ No newline at end of file diff --git "a/leetcode/941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.py" "b/leetcode_Python/941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.py" similarity index 98% rename from "leetcode/941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.py" rename to "leetcode_Python/941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.py" index 1b468c9..1e129a9 100644 --- "a/leetcode/941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.py" +++ "b/leetcode_Python/941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.py" @@ -1,7 +1,7 @@ -# 峰顶左边递增,右边递减,且左右不含重复元素 -class Solution(object): - def validMountainArray(self, A): - if not A: - return False - i = A.index(max(A)) +# 峰顶左边递增,右边递减,且左右不含重复元素 +class Solution(object): + def validMountainArray(self, A): + if not A: + return False + i = A.index(max(A)) return i!=0 and i!=len(A)-1 and sorted(set(A[:i])) == A[:i] and sorted(set(A[i:]))[::-1] == A[i:] \ No newline at end of file diff --git "a/leetcode/942.\345\242\236\345\207\217\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" "b/leetcode_Python/942.\345\242\236\345\207\217\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" similarity index 96% rename from "leetcode/942.\345\242\236\345\207\217\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" rename to "leetcode_Python/942.\345\242\236\345\207\217\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" index 713cd80..7637a06 100644 --- "a/leetcode/942.\345\242\236\345\207\217\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" +++ "b/leetcode_Python/942.\345\242\236\345\207\217\345\255\227\347\254\246\344\270\262\345\214\271\351\205\215.py" @@ -1,14 +1,14 @@ -# 增时添加左边一个数,减时添加右边一个数,遍历完S再添加最后剩下的一个数 -class Solution(object): - def diStringMatch(self, S): - res = [] - l, r = 0, len(S) - for s in S: - if s == 'I': - res.append(l) - l += 1 - if s == 'D': - res.append(r) - r -= 1 - res.append(l) +# 增时添加左边一个数,减时添加右边一个数,遍历完S再添加最后剩下的一个数 +class Solution(object): + def diStringMatch(self, S): + res = [] + l, r = 0, len(S) + for s in S: + if s == 'I': + res.append(l) + l += 1 + if s == 'D': + res.append(r) + r -= 1 + res.append(l) return res \ No newline at end of file diff --git "a/leetcode/944.\345\210\240\345\210\227\351\200\240\345\272\217.py" "b/leetcode_Python/944.\345\210\240\345\210\227\351\200\240\345\272\217.py" similarity index 97% rename from "leetcode/944.\345\210\240\345\210\227\351\200\240\345\272\217.py" rename to "leetcode_Python/944.\345\210\240\345\210\227\351\200\240\345\272\217.py" index eebe909..571b196 100644 --- "a/leetcode/944.\345\210\240\345\210\227\351\200\240\345\272\217.py" +++ "b/leetcode_Python/944.\345\210\240\345\210\227\351\200\240\345\272\217.py" @@ -1,8 +1,8 @@ -# 将A数组解压,遍历解压列表,若元组非降序排列,则需要删除一个索引 -class Solution(object): - def minDeletionSize(self, A): - res = 0 - for i in zip(*A): - if list(i) != sorted(i): - res += 1 +# 将A数组解压,遍历解压列表,若元组非降序排列,则需要删除一个索引 +class Solution(object): + def minDeletionSize(self, A): + res = 0 + for i in zip(*A): + if list(i) != sorted(i): + res += 1 return res \ No newline at end of file diff --git "a/leetcode/950.\346\214\211\351\200\222\345\242\236\351\241\272\345\272\217\346\230\276\347\244\272\345\215\241\347\211\214.py" "b/leetcode_Python/950.\346\214\211\351\200\222\345\242\236\351\241\272\345\272\217\346\230\276\347\244\272\345\215\241\347\211\214.py" similarity index 97% rename from "leetcode/950.\346\214\211\351\200\222\345\242\236\351\241\272\345\272\217\346\230\276\347\244\272\345\215\241\347\211\214.py" rename to "leetcode_Python/950.\346\214\211\351\200\222\345\242\236\351\241\272\345\272\217\346\230\276\347\244\272\345\215\241\347\211\214.py" index f89f187..8538485 100644 --- "a/leetcode/950.\346\214\211\351\200\222\345\242\236\351\241\272\345\272\217\346\230\276\347\244\272\345\215\241\347\211\214.py" +++ "b/leetcode_Python/950.\346\214\211\351\200\222\345\242\236\351\241\272\345\272\217\346\230\276\347\244\272\345\215\241\347\211\214.py" @@ -1,13 +1,13 @@ -# 逆向操作 -class Solution(object): - def deckRevealedIncreasing(self, deck): - # 将原数组倒序排序 - deck.sort(reverse=True) - res = [] - while deck: - # 如果新数组有元素,则将最后一个元素移到首位 - if res: - res = [res[-1]] + res[:-1] - # 再插入新元素到首位 - res.insert(0, deck.pop(0)) +# 逆向操作 +class Solution(object): + def deckRevealedIncreasing(self, deck): + # 将原数组倒序排序 + deck.sort(reverse=True) + res = [] + while deck: + # 如果新数组有元素,则将最后一个元素移到首位 + if res: + res = [res[-1]] + res[:-1] + # 再插入新元素到首位 + res.insert(0, deck.pop(0)) return res \ No newline at end of file diff --git "a/leetcode/951.\347\277\273\350\275\254\347\255\211\344\273\267\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/951.\347\277\273\350\275\254\347\255\211\344\273\267\344\272\214\345\217\211\346\240\221.py" similarity index 98% rename from "leetcode/951.\347\277\273\350\275\254\347\255\211\344\273\267\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/951.\347\277\273\350\275\254\347\255\211\344\273\267\344\272\214\345\217\211\346\240\221.py" index 2c5bf7f..06841a6 100644 --- "a/leetcode/951.\347\277\273\350\275\254\347\255\211\344\273\267\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/951.\347\277\273\350\275\254\347\255\211\344\273\267\344\272\214\345\217\211\346\240\221.py" @@ -1,9 +1,9 @@ -# 根结点必须相等,子结点左左且右右相等或左右且右左相等 -class Solution(object): - def flipEquiv(self, root1, root2): - if not root1 and not root2: - return True - if root1 and root2 and root1.val == root2.val: - return (self.flipEquiv(root1.left, root2.right) and self.flipEquiv(root1.right, root2.left)) \ - or (self.flipEquiv(root1.left, root2.left) and self.flipEquiv(root1.right, root2.right)) +# 根结点必须相等,子结点左左且右右相等或左右且右左相等 +class Solution(object): + def flipEquiv(self, root1, root2): + if not root1 and not root2: + return True + if root1 and root2 and root1.val == root2.val: + return (self.flipEquiv(root1.left, root2.right) and self.flipEquiv(root1.right, root2.left)) \ + or (self.flipEquiv(root1.left, root2.left) and self.flipEquiv(root1.right, root2.right)) return False \ No newline at end of file diff --git "a/leetcode/961.\351\207\215\345\244\215 N \346\254\241\347\232\204\345\205\203\347\264\240.py" "b/leetcode_Python/961.\351\207\215\345\244\215 N \346\254\241\347\232\204\345\205\203\347\264\240.py" similarity index 96% rename from "leetcode/961.\351\207\215\345\244\215 N \346\254\241\347\232\204\345\205\203\347\264\240.py" rename to "leetcode_Python/961.\351\207\215\345\244\215 N \346\254\241\347\232\204\345\205\203\347\264\240.py" index 64a4302..1441c24 100644 --- "a/leetcode/961.\351\207\215\345\244\215 N \346\254\241\347\232\204\345\205\203\347\264\240.py" +++ "b/leetcode_Python/961.\351\207\215\345\244\215 N \346\254\241\347\232\204\345\205\203\347\264\240.py" @@ -1,16 +1,16 @@ -# 方法一:遍历集合,边统计元素的个数 -class Solution(object): - def repeatedNTimes(self, A): - n = len(A)/2 - for i in A: - if A.count(i) == n: - return i - -# 方法二:利用字典存放字符与对应个数 -class Solution(object): - def repeatedNTimes(self, A): - d = collections.Counter(A) - n = len(A)/2 - for i in set(A): - if d[i] == n: +# 方法一:遍历集合,边统计元素的个数 +class Solution(object): + def repeatedNTimes(self, A): + n = len(A)/2 + for i in A: + if A.count(i) == n: + return i + +# 方法二:利用字典存放字符与对应个数 +class Solution(object): + def repeatedNTimes(self, A): + d = collections.Counter(A) + n = len(A)/2 + for i in set(A): + if d[i] == n: return i \ No newline at end of file diff --git "a/leetcode/965.\345\215\225\345\200\274\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/965.\345\215\225\345\200\274\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/965.\345\215\225\345\200\274\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/965.\345\215\225\345\200\274\344\272\214\345\217\211\346\240\221.py" index 9afdd84..55ceb8e 100644 --- "a/leetcode/965.\345\215\225\345\200\274\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/965.\345\215\225\345\200\274\344\272\214\345\217\211\346\240\221.py" @@ -1,24 +1,24 @@ -# 前序遍历获取所有节点值,判断求和结果是否与第一个值的n倍相同 -class Solution(object): - def isUnivalTree(self, root): - """ - :type root: TreeNode - :rtype: bool - """ - self.res = [] - def preOrder(root): - if root: - self.res.append(root.val) - preOrder(root.left) - preOrder(root.right) - preOrder(root) - return sum(self.res) == self.res[0]*len(self.res) - -# 递归判断,如果结点与左右结点值不相等,则返回false,否则返回true -class Solution2(object): - def isUnivalTree(self, root): - if root: - if (root.left and root.val != root.left.val) or (root.right and root.val != root.right.val): - return False - return self.isUnivalTree(root.left) and self.isUnivalTree(root.right) +# 前序遍历获取所有节点值,判断求和结果是否与第一个值的n倍相同 +class Solution(object): + def isUnivalTree(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + self.res = [] + def preOrder(root): + if root: + self.res.append(root.val) + preOrder(root.left) + preOrder(root.right) + preOrder(root) + return sum(self.res) == self.res[0]*len(self.res) + +# 递归判断,如果结点与左右结点值不相等,则返回false,否则返回true +class Solution2(object): + def isUnivalTree(self, root): + if root: + if (root.left and root.val != root.left.val) or (root.right and root.val != root.right.val): + return False + return self.isUnivalTree(root.left) and self.isUnivalTree(root.right) return True \ No newline at end of file diff --git "a/leetcode/968.\347\233\221\346\216\247\344\272\214\345\217\211\346\240\221.py" "b/leetcode_Python/968.\347\233\221\346\216\247\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "leetcode/968.\347\233\221\346\216\247\344\272\214\345\217\211\346\240\221.py" rename to "leetcode_Python/968.\347\233\221\346\216\247\344\272\214\345\217\211\346\240\221.py" index 63e96f9..bb92ecd 100644 --- "a/leetcode/968.\347\233\221\346\216\247\344\272\214\345\217\211\346\240\221.py" +++ "b/leetcode_Python/968.\347\233\221\346\216\247\344\272\214\345\217\211\346\240\221.py" @@ -1,49 +1,49 @@ -#0:该结点附近有未被监视结点,安装监控器 -#1:该结点周围有监控器或该结点不存在,都不用安装监控器 -#2:该结点附近没有监控器,表示其附近需要监控器 -class Solution(object): - def minCameraCover(self, root): - self.res = 0 - if self.dfs(root) == 2: - self.res += 1 - return self.res - - def dfs(self, root): - if not root: - return 1 - left = self.dfs(root.left) - right = self.dfs(root.right) - if left == 2 or right == 2: - self.res += 1 - return 0 - elif left == 0 or right == 0: - return 1 - else: - return 2 - -# 贪心算法,自底向上,在有孩子的结点上安装摄像头最多可监控4个结点,即自己、左右孩子、父节点 -class Solution2(object): - def minCameraCover(self, root): - if not root.left and not root.right: - return 1 - # 层次遍历将所有节点保存下来 - parents, nodes, cur = {root:None}, [], collections.deque([root]) - while cur: - node = cur.popleft() - if node.left: - parents[node.left] = node - cur.append(node.left) - if node.right: - parents[node.right] = node - cur.append(node.right) - nodes.append(node) - - vis = {} - for node in nodes[::-1]: - parent = parents[node] - # 若当前结点被监控,即当前结点或左右孩子安装了摄像头,则跳过遍历下一结点 - if node in vis or node.left in vis or node.right in vis: - continue - # 否则在父节点安装摄像头 - vis[parent] = 1 +#0:该结点附近有未被监视结点,安装监控器 +#1:该结点周围有监控器或该结点不存在,都不用安装监控器 +#2:该结点附近没有监控器,表示其附近需要监控器 +class Solution(object): + def minCameraCover(self, root): + self.res = 0 + if self.dfs(root) == 2: + self.res += 1 + return self.res + + def dfs(self, root): + if not root: + return 1 + left = self.dfs(root.left) + right = self.dfs(root.right) + if left == 2 or right == 2: + self.res += 1 + return 0 + elif left == 0 or right == 0: + return 1 + else: + return 2 + +# 贪心算法,自底向上,在有孩子的结点上安装摄像头最多可监控4个结点,即自己、左右孩子、父节点 +class Solution2(object): + def minCameraCover(self, root): + if not root.left and not root.right: + return 1 + # 层次遍历将所有节点保存下来 + parents, nodes, cur = {root:None}, [], collections.deque([root]) + while cur: + node = cur.popleft() + if node.left: + parents[node.left] = node + cur.append(node.left) + if node.right: + parents[node.right] = node + cur.append(node.right) + nodes.append(node) + + vis = {} + for node in nodes[::-1]: + parent = parents[node] + # 若当前结点被监控,即当前结点或左右孩子安装了摄像头,则跳过遍历下一结点 + if node in vis or node.left in vis or node.right in vis: + continue + # 否则在父节点安装摄像头 + vis[parent] = 1 return sum(vis.values()) \ No newline at end of file diff --git "a/leetcode/979.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\210\206\351\205\215\347\241\254\345\270\201.py" "b/leetcode_Python/979.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\210\206\351\205\215\347\241\254\345\270\201.py" similarity index 97% rename from "leetcode/979.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\210\206\351\205\215\347\241\254\345\270\201.py" rename to "leetcode_Python/979.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\210\206\351\205\215\347\241\254\345\270\201.py" index 15cf8d4..84f02fe 100644 --- "a/leetcode/979.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\210\206\351\205\215\347\241\254\345\270\201.py" +++ "b/leetcode_Python/979.\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\345\210\206\351\205\215\347\241\254\345\270\201.py" @@ -1,20 +1,20 @@ -# 从后序遍历的第一个叶子节点开始,假设自己有x个金币,剩余x-1个金币都还给父节点,x-1可能为负数、0、正数 -# x-1 < 0 说明不够金币,需要从父节点获得,因此子节点有|x-1|个入方向的操作,次数加上|x-1| -# x-1 == 0 说明刚好,无需与父节点有金币的交换,次数加0 -# x-1 > 0 说明有多余的金币,需要交给父节点,因此子节点有x-1个出方向的操作,次数加上|x-1| -class Solution(object): - def distributeCoins(self, root): - res = [0] - - def postOrder(root): - if not root: - return 0 - left = postOrder(root.left) - right = postOrder(root.right) - diff = root.val + left + right - 1 - res[0] += abs(diff) - return diff - - postOrder(root) - return res[0] - +# 从后序遍历的第一个叶子节点开始,假设自己有x个金币,剩余x-1个金币都还给父节点,x-1可能为负数、0、正数 +# x-1 < 0 说明不够金币,需要从父节点获得,因此子节点有|x-1|个入方向的操作,次数加上|x-1| +# x-1 == 0 说明刚好,无需与父节点有金币的交换,次数加0 +# x-1 > 0 说明有多余的金币,需要交给父节点,因此子节点有x-1个出方向的操作,次数加上|x-1| +class Solution(object): + def distributeCoins(self, root): + res = [0] + + def postOrder(root): + if not root: + return 0 + left = postOrder(root.left) + right = postOrder(root.right) + diff = root.val + left + right - 1 + res[0] += abs(diff) + return diff + + postOrder(root) + return res[0] + diff --git "a/leetcode/984.\344\270\215\345\220\253 AAA \346\210\226 BBB \347\232\204\345\255\227\347\254\246\344\270\262.py" "b/leetcode_Python/984.\344\270\215\345\220\253 AAA \346\210\226 BBB \347\232\204\345\255\227\347\254\246\344\270\262.py" similarity index 96% rename from "leetcode/984.\344\270\215\345\220\253 AAA \346\210\226 BBB \347\232\204\345\255\227\347\254\246\344\270\262.py" rename to "leetcode_Python/984.\344\270\215\345\220\253 AAA \346\210\226 BBB \347\232\204\345\255\227\347\254\246\344\270\262.py" index 6aa3736..07effc3 100644 --- "a/leetcode/984.\344\270\215\345\220\253 AAA \346\210\226 BBB \347\232\204\345\255\227\347\254\246\344\270\262.py" +++ "b/leetcode_Python/984.\344\270\215\345\220\253 AAA \346\210\226 BBB \347\232\204\345\255\227\347\254\246\344\270\262.py" @@ -1,21 +1,21 @@ -class Solution(object): - def strWithout3a3b(self, A, B): - # 使A大于B - a, b = 'a', 'b' - if A < B: - a, b = b, a - A, B = B, A - - res = '' - # A的数量多于B时构造 'aab',否则构造 'ab' - while A > 0 or B > 0: - if A > 0: - res += a - A -= 1 - if A > B: - res += a - A -= 1 - if B > 0: - res += b - B -= 1 +class Solution(object): + def strWithout3a3b(self, A, B): + # 使A大于B + a, b = 'a', 'b' + if A < B: + a, b = b, a + A, B = B, A + + res = '' + # A的数量多于B时构造 'aab',否则构造 'ab' + while A > 0 or B > 0: + if A > 0: + res += a + A -= 1 + if A > B: + res += a + A -= 1 + if B > 0: + res += b + B -= 1 return res \ No newline at end of file diff --git "a/leetcode/991.\345\235\217\344\272\206\347\232\204\350\256\241\347\256\227\345\231\250.py" "b/leetcode_Python/991.\345\235\217\344\272\206\347\232\204\350\256\241\347\256\227\345\231\250.py" similarity index 96% rename from "leetcode/991.\345\235\217\344\272\206\347\232\204\350\256\241\347\256\227\345\231\250.py" rename to "leetcode_Python/991.\345\235\217\344\272\206\347\232\204\350\256\241\347\256\227\345\231\250.py" index f25974b..1eb90d9 100644 --- "a/leetcode/991.\345\235\217\344\272\206\347\232\204\350\256\241\347\256\227\345\231\250.py" +++ "b/leetcode_Python/991.\345\235\217\344\272\206\347\232\204\350\256\241\347\256\227\345\231\250.py" @@ -1,16 +1,16 @@ -# 逆向求解,对Y进行除、加逐步逼近X -class Solution(object): - def brokenCalc(self, X, Y): - if X > Y: - return X - Y - res = 0 - while X < Y: - # Y为奇数时除后非整所以只能加 - if Y % 2: - Y += 1 - # Y为偶数时就除,逼近X - else: - Y /= 2 - res += 1 - # Y比X小后逐步加直到等于X +# 逆向求解,对Y进行除、加逐步逼近X +class Solution(object): + def brokenCalc(self, X, Y): + if X > Y: + return X - Y + res = 0 + while X < Y: + # Y为奇数时除后非整所以只能加 + if Y % 2: + Y += 1 + # Y为偶数时就除,逼近X + else: + Y /= 2 + res += 1 + # Y比X小后逐步加直到等于X return X - Y + res \ No newline at end of file diff --git "a/leetcode/993.\344\272\214\345\217\211\346\240\221\347\232\204\345\240\202\345\205\204\345\274\237\350\212\202\347\202\271.py" "b/leetcode_Python/993.\344\272\214\345\217\211\346\240\221\347\232\204\345\240\202\345\205\204\345\274\237\350\212\202\347\202\271.py" similarity index 97% rename from "leetcode/993.\344\272\214\345\217\211\346\240\221\347\232\204\345\240\202\345\205\204\345\274\237\350\212\202\347\202\271.py" rename to "leetcode_Python/993.\344\272\214\345\217\211\346\240\221\347\232\204\345\240\202\345\205\204\345\274\237\350\212\202\347\202\271.py" index 9f43fcc..4b68251 100644 --- "a/leetcode/993.\344\272\214\345\217\211\346\240\221\347\232\204\345\240\202\345\205\204\345\274\237\350\212\202\347\202\271.py" +++ "b/leetcode_Python/993.\344\272\214\345\217\211\346\240\221\347\232\204\345\240\202\345\205\204\345\274\237\350\212\202\347\202\271.py" @@ -1,28 +1,28 @@ -# 层次遍历判断 -class Solution(object): - def isCousins(self, root, x, y): - cur_level = [root] - while cur_level: - cur_val, n = [], len(cur_level) - # 遍历当前层结点,并获取下一层结点 - for _ in range(n): - node = cur_level.pop(0) - if node: - cur_val.append(node.val) - cur_level.append(node.left) - cur_level.append(node.right) - # 结点为空则填充0占位置 - else: - cur_val.append(0) - # 两个值在同一层 - if x in cur_val and y in cur_val: - index1, index2 = cur_val.index(x), cur_val.index(y) - index1, index2 = sorted([index1, index2]) - # 两结点相邻且较小索引为偶数说明两节点有共同父节点 - if index2 - index1 == 1 and index1 % 2 == 0: - return False - return True - # 两个值不在同一层 - if x in cur_val or y in cur_val: - return False +# 层次遍历判断 +class Solution(object): + def isCousins(self, root, x, y): + cur_level = [root] + while cur_level: + cur_val, n = [], len(cur_level) + # 遍历当前层结点,并获取下一层结点 + for _ in range(n): + node = cur_level.pop(0) + if node: + cur_val.append(node.val) + cur_level.append(node.left) + cur_level.append(node.right) + # 结点为空则填充0占位置 + else: + cur_val.append(0) + # 两个值在同一层 + if x in cur_val and y in cur_val: + index1, index2 = cur_val.index(x), cur_val.index(y) + index1, index2 = sorted([index1, index2]) + # 两结点相邻且较小索引为偶数说明两节点有共同父节点 + if index2 - index1 == 1 and index1 % 2 == 0: + return False + return True + # 两个值不在同一层 + if x in cur_val or y in cur_val: + return False return False \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java/DoneTitle.txt" "b/\345\211\221\346\214\207Offer_Java/DoneTitle.txt" new file mode 100644 index 0000000..42a10a6 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java/DoneTitle.txt" @@ -0,0 +1,67 @@ +1. 二维数组中的查找 +2. 替换空格 +3. 从尾到头打印链表 +4. 重建二叉树 +5. 用两个栈实现队列 +6. 旋转数组的最小数字 +7. 斐波那契数列 +8. 跳台阶 +9. 变态跳台阶 +10. 矩形覆盖 +11. 二进制中1的个数 +12. 数值的整数次方 +13. 调整数组顺序使奇数位于偶数前面 +14. 链表中倒数第k个结点 +15. 反转链表 +16. 合并两个排序的链表 +17. 树的子结构 +18. 二叉树的镜像 +19. 顺时针打印矩阵 +20. 包含min函数的栈 +21. 栈的压入、弹出序列 +22. 从上往下打印二叉树 +23. 二叉搜索树的后序遍历序列 +24. 二叉树中和为某一值的路径 +25. 复杂链表的复制 +26. 二叉搜索树与双向链表 +27. 字符串的排列 +28. 数组中出现次数超过一半的数字 +29. 最小的K个数 +30. 连续子数组的最大和 +31. 整数中1出现的次数(从1到n整数中1出现的次数) +32. 把数组排成最小的数 +33. 丑数 +34. 第一个只出现一次的字符 +35. 数组中的逆序对 +36. 两个链表的第一个公共结点 +37. 数字在排序数组中出现的次数 +38. 二叉树的深度 +39. 平衡二叉树 +40. 数组中只出现一次的数字 +41. 和为S的连续正数序列 +42. 和为S的两个数字 +43. 左旋转字符串 +44. 翻转单词顺序列 +45. 扑克牌顺子 +46. 孩子们的游戏(圆圈中最后剩下的数) +47. 求1+2+3+...+n +48. 不用加减乘除做加法 +49. 把字符串转换成整数 +50. 数组中重复的数字 +51. 构建乘积数组 +52. 正则表达式匹配 +53. 表示数值的字符串 +54. 字符流中第一个不重复的字符 +55. 链表中环的入口结点 +56. 删除链表中重复的结点 +57. 二叉树的下一个结点 +58. 对称的二叉树 +59. 按之字形顺序打印二叉树 +60. 把二叉树打印成多行 +61. 序列化二叉树 +62. 二叉搜索树的第k个结点 +63. 数据流中的中位数 +64. 滑动窗口的最大值 +65. 矩阵中的路径 +66. 机器人的运动范围 +67. 剪绳子 \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java/Test22.java" "b/\345\211\221\346\214\207Offer_Java/Test22.java" index 34bc79d..ad5f702 100644 --- "a/\345\211\221\346\214\207Offer_Java/Test22.java" +++ "b/\345\211\221\346\214\207Offer_Java/Test22.java" @@ -16,6 +16,7 @@ public TreeNode(int val) { } */ +// 从上往下打印二叉树 public class Test22 { public ArrayList PrintFromTopToBottom(TreeNode root) { ArrayList list = new ArrayList<>(); diff --git "a/\345\211\221\346\214\207Offer_Java/Test37.java" "b/\345\211\221\346\214\207Offer_Java/Test37.java" index a4a4381..17a8385 100644 --- "a/\345\211\221\346\214\207Offer_Java/Test37.java" +++ "b/\345\211\221\346\214\207Offer_Java/Test37.java" @@ -2,7 +2,7 @@ // 数字在排序数组中出现的次数 public class Test37 { - public int GetNumberOfK(int [] array , int k) { + public int GetNumberOfK(int[] array , int k) { int count = 0; for (int i = 0; i < array.length; i++) { if (array[i] == k) { diff --git "a/\345\211\221\346\214\207Offer_Java/Test39.java" "b/\345\211\221\346\214\207Offer_Java/Test39.java" index 0af713b..4bfa1fd 100644 --- "a/\345\211\221\346\214\207Offer_Java/Test39.java" +++ "b/\345\211\221\346\214\207Offer_Java/Test39.java" @@ -6,16 +6,16 @@ public boolean IsBalanced_Solution(TreeNode root) { if (root == null) { return true; } - if (Math.abs(TreeDepth(root.left) - TreeDepth(root.right)) > 1) { + if (Math.abs(treeDepth(root.left) - treeDepth(root.right)) > 1) { return false; } return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right); } - public int TreeDepth(TreeNode root) { + public int treeDepth(TreeNode root) { if (root == null) { return 0; } - return 1 + Math.max(TreeDepth(root.left), TreeDepth(root.right)); + return 1 + Math.max(treeDepth(root.left), treeDepth(root.right)); } } diff --git "a/\345\211\221\346\214\207Offer_Java/Test42.java" "b/\345\211\221\346\214\207Offer_Java/Test42.java" index cf530c7..e3b73b2 100644 --- "a/\345\211\221\346\214\207Offer_Java/Test42.java" +++ "b/\345\211\221\346\214\207Offer_Java/Test42.java" @@ -4,7 +4,7 @@ // 和为S的两个数字 public class Test42 { - public ArrayList FindNumbersWithSum(int [] array, int sum) { + public ArrayList FindNumbersWithSum(int[] array, int sum) { ArrayList list = new ArrayList<>(); int left = 0, right = array.length-1; while (left < right) { diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/DoneTitle.txt" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/DoneTitle.txt" new file mode 100644 index 0000000..18c5410 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/DoneTitle.txt" @@ -0,0 +1,81 @@ +3. 数组中重复的数字 +4. 二维数组中的查找 +5. 替换空格 +6. 从尾到头打印链表 +7. 重建二叉树 +8. 二叉树的下一个结点 +9. 用两个栈实现队列 +10. 斐波那契数列 +11. 旋转数组的最小数字 +12. 矩阵中的路径 +13. 机器人的运动范围 +14. 剪绳子 +15. 二进制中1的个数 +16. 数值的整数次方 +17. 打印从1到最大的n位数 +18. 删除链表的节点 +19. 正则表达式匹配 +20. 表示数值的字符串 +21. 调整数组顺序使奇数位于偶数前面 +22. 链表中倒数第k个结点 +23. 链表中环的入口结点 +24. 反转链表 +25. 合并两个排序的链表 +26. 树的子结构 +27. 二叉树的镜像 +28. 对称的二叉树 +29. 顺时针打印矩阵 +30. 包含min函数的栈 +31. 栈的压入、弹出序列 +32. 从上往下打印二叉树 +33. 二叉搜索树的后序遍历序列 +34. 二叉树中和为某一值的路径(二) +35. 复杂链表的复制 +36. 二叉搜索树与双向链表 +37. 序列化二叉树 +38. 字符串的排列 +39. 数组中出现次数超过一半的数字 +40. 最小的K个数 +41. 数据流中的中位数 +42. 连续子数组的最大和 +43. 整数中1出现的次数(从1到n整数中1出现的次数) +44. 数字序列中某一位的数字 +45. 把数组排成最小的数 +46. 把数字翻译成字符串 +47. 礼物的最大价值 +48. 最长不含重复字符的子字符串 +49. 丑数 +50. 第一个只出现一次的字符 +51. 数组中的逆序对 +52. 两个链表的第一个公共结点 +53. 数字在排序数组中出现的次数 +54. 二叉搜索树的第k个结点 +55. 二叉树的深度 +56. 数组中只出现一次的两个数字 +57. 和为S的两个数字 +58. 左旋转字符串 +59. 滑动窗口的最大值 +61. 扑克牌顺子 +62. 孩子们的游戏(圆圈中最后剩下的数) +63. 买卖股票的最好时机(一) +64. 求1+2+3+...+n +65. 不用加减乘除做加法 +66. 构建乘积数组 +67. 把字符串转换成整数(atoi) +68. 二叉搜索树的最近公共祖先 +69. 跳台阶 +70. 矩形覆盖 +71. 跳台阶扩展问题 +73. 翻转单词顺序列 +74. 和为S的连续正数序列 +75. 字符流中第一个不重复的字符 +76. 删除链表中重复的结点 +77. 按之字形顺序打印二叉树 +78. 把二叉树打印成多行 +79. 判断是不是平衡二叉树 +81. 调整数组顺序使奇数位于偶数前面(二) +82. 二叉树中和为某一值的路径(一) +83. 剪绳子(进阶版) +84. 二叉树中和为某一值的路径(三) +85. 连续子数组的最大和(二) +86. 在二叉树中找到两个节点的最近公共祖先 diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/DoneType.txt" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/DoneType.txt" new file mode 100644 index 0000000..133705f --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/DoneType.txt" @@ -0,0 +1,131 @@ +分类目录 +一、链表 +二、树 +三、队列、栈 +四、搜索算法 +五、动态规划 +六、回溯 +七、排序 +八、位运算 +九、模拟 +十、数组 +十一、字符串 +十二、数学 + + +一、链表 +6. 从尾到头打印链表(递归,列表) +18. 删除链表的节点(迭代,三指针) +22. 链表中倒数第k个结点(迭代,快慢指针) +23. 链表中环的入口结点(列表,迭代,三指针) +24. 反转链表(迭代,三指针) +25. 合并两个排序的链表(递归) +35. 复杂链表的复制(迭代,哈希表) +52. 两个链表的第一个公共结点(迭代) +76. 删除链表中重复的结点(迭代,双指针) + + +二、树 +7. 重建二叉树 +8. 二叉树的下一个结点 +26. 树的子结构 +27. 二叉树的镜像 +28. 对称的二叉树 +32. 从上往下打印二叉树 +33. 二叉搜索树的后序遍历序列 +34. 二叉树中和为某一值的路径(二) +36. 二叉搜索树与双向链表 +37. 序列化二叉树 +54. 二叉搜索树的第k个结点 +55. 二叉树的深度 +68. 二叉搜索树的最近公共祖先 +77. 按之字形顺序打印二叉树 +78. 把二叉树打印成多行 +79. 判断是不是平衡二叉树 +82. 二叉树中和为某一值的路径(一) +84. 二叉树中和为某一值的路径(三) +86. 在二叉树中找到两个节点的最近公共祖先 + + +三、队列、栈 +9. 用两个栈实现队列(互倒) +30. 包含min函数的栈(迭代取最小) +31. 栈的压入、弹出序列 +59. 滑动窗口的最大值(单调递减队列) +73. 翻转单词顺序列(切割) + + +四、搜索算法 +4. 二维数组中的查找(二分查找) +11. 旋转数组的最小数字(二分查找) +44. 数字序列中某一位的数字 +53. 数字在排序数组中出现的次数 + + +五、动态规划 +10. 斐波那契数列 +14. 剪绳子 +19. 正则表达式匹配 +42. 连续子数组的最大和 +46. 把数字翻译成字符串 +47. 礼物的最大价值 +48. 最长不含重复字符的子字符串 +63. 买卖股票的最好时机(一) +69. 跳台阶 +70. 矩形覆盖 +71. 跳台阶扩展问题 +85. 连续子数组的最大和(二) + + +六、回溯、BFS +12. 矩阵中的路径 +13. 机器人的运动范围 +38. 字符串的排列 + + +七、排序 +40. 最小的K个数 +41. 数据流中的中位数 +51. 数组中的逆序对 + + +八、位运算 +15. 二进制中1的个数 +16. 数值的整数次方 +56. 数组中只出现一次的两个数字 +64. 求1+2+3+...+n +65. 不用加减乘除做加法 + + +九、模拟 +20. 表示数值的字符串 +29. 顺时针打印矩阵 +61. 扑克牌顺子 +67. 把字符串转换成整数(atoi) + + +十、数组 +3. 数组中重复的数字(哈希,集合,排序) +17. 打印从1到最大的n位数 +21. 调整数组顺序使奇数位于偶数前面 +39. 数组中出现次数超过一半的数字 +45. 把数组排成最小的数 +49. 丑数 +57. 和为S的两个数字 +62. 孩子们的游戏(圆圈中最后剩下的数) +66. 构建乘积数组 +74. 和为S的连续正数序列 +81. 调整数组顺序使奇数位于偶数前面(二) + + +十一、字符串 +5. 替换空格(增删、构造、替换) +43. 整数中1出现的次数(从1到n整数中1出现的次数) +50. 第一个只出现一次的字符(数组映射、哈希表) +58. 左旋转字符串(截取) +75. 字符流中第一个不重复的字符 + + +十二、数学 +14. 剪绳子 +83. 剪绳子(进阶版) diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ03.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ03.java" new file mode 100644 index 0000000..791c496 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ03.java" @@ -0,0 +1,67 @@ +// 3. 数组中重复的数字 + + +/* +原地哈希:把数字交换到正确的位置上 +1、由于数字都在0到n-1的范围内,所以数字和索引可以一一对应,不对应时说明重复了 +2、遍历数组,如果索引与数字相同,说明该数字已经排序好了,继续下一个数字判断 +3、如果索引与数字不同,则将数字交换到正确的位置上 +4、当第二次碰到重复数字时,由于在正确的位置上已经有该值了,则返回该重复数字 + +元素:3 1 2 3 4 +索引:0 1 2 3 4 + */ +public class Solution { + public int duplicate (int[] numbers) { + for (int i = 0; i < numbers.length; i++) { + if (i == numbers[i]) { + continue; + } + if (numbers[i] == numbers[numbers[i]]) { + return numbers[i]; + } + swap(numbers, i, numbers[i]); + } + return -1; + } + + private void swap(int[] numbers, int x, int y) { + int temp = numbers[x]; + numbers[x] = numbers[y]; + numbers[y] = temp; + } +} + + +/* +集合:用HashSet存放元素,存在则返回,不存在则添加,遍历完没找到则返回-1 + */ +public class Solution { + public int duplicate (int[] numbers) { + Set set = new HashSet<>(); + for (int num : numbers) { + if (set.contains(num)) { + return num; + } else { + set.add(num); + } + } + return -1; + } +} + + +/* +排序:排序后判断当前数字与前一数字是否相同,相同则返回 + */ +public class Solution { + public int duplicate (int[] numbers) { + Arrays.sort(numbers); + for (int i = 1; i < numbers.length; i++) { + if (numbers[i] == numbers[i - 1]) { + return numbers[i]; + } + } + return -1; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ04.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ04.java" new file mode 100644 index 0000000..30d7c2a --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ04.java" @@ -0,0 +1,22 @@ +// 4. 二维数组中的查找 + + +/* +二分查找:从左下角到右上角遍历 + */ +public class Solution { + public boolean Find(int target, int[][] array) { + int row = array.length - 1; + int col = 0; + while (row >= 0 && col <= array[0].length - 1) { + if (array[row][col] > target) { + row--; + } else if (array[row][col] < target) { + col++; + } else { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ05.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ05.java" new file mode 100644 index 0000000..e0fe372 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ05.java" @@ -0,0 +1,37 @@ +// 5. 替换空格 + + +/* +增删、构造、替换 + */ +public class Solution { + // 通过删增来替换字符串 + public String replaceSpace(StringBuffer str) { + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == ' ') { + str.deleteCharAt(i); + str.insert(i, "%20"); + } + } + return str.toString(); + } + + // 构造新字符串 + public String replaceSpace2(StringBuffer str) { + String res = ""; + for (int i = 0; i < str.length(); i++) { + char s = str.charAt(i); + if (s == ' ') { + res += "%20"; + } else { + res += s; + } + } + return res; + } + + // 调用替换字符串方法 + public String replaceSpace3(StringBuffer str) { + return str.toString().replaceAll("\\s", "%20"); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ06.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ06.java" new file mode 100644 index 0000000..42d48b5 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ06.java" @@ -0,0 +1,44 @@ +// 6. 从尾到头打印链表 + + +/* +class ListNode { + int val; + ListNode next = null; + ListNode(int val) { + this.val = val; + } +} +*/ + + +/* +递归:递归到尾部后,逐层将节点值添加到列表 + */ +public class Solution { + private ArrayList list = new ArrayList(); + + public ArrayList printListFromTailToHead(ListNode listNode) { + if (listNode == null) { + return list; + } + printListFromTailToHead(listNode.next); + list.add(listNode.val); + return list; + } +} + + +/* +列表:遍历节点,列表存放节点值,每次插入到头部 + */ +public class Solution { + public ArrayList printListFromTailToHead(ListNode listNode) { + ArrayList list = new ArrayList<>(); + while (listNode != null) { + list.add(0, listNode.val); + listNode = listNode.next; + } + return list; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ07.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ07.java" new file mode 100644 index 0000000..f341a96 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ07.java" @@ -0,0 +1,41 @@ +// 7. 重建二叉树 + + +/* +class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { + val = x; + } +} +*/ + + +/* +递归: +1、方法功能:入参是前序和中序数组,获取前序数组首元素,构造节点,然后返回该节点 +2、终止条件:两个数组为空,结束 +3、递归逻辑: + 1)由于需要构造左右节点,所以要将数组拆分成左右子树的两部分数组 + 2)先找到头节点在中序数组的位置,将中序数组拆分成左右两部分,根据中序数组左半部分的长度 将前序数组也拆分成左右两部分 + 3)需要构造左右节点,调用同样的方法,把两个数组传进去,得到左右节点 + 4)根节点连接左右节点,返回根节点 +4、返回值:两个数组构造出来的头节点 + */ +public class Solution { + public TreeNode reConstructBinaryTree(int[] pre, int[] in) { + if (pre.length == 0 || in.length == 0) { + return null; + } + TreeNode root = new TreeNode(pre[0]); + for (int i = 0; i < in.length; i++) { + if (pre[0] == in[i]) { + root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i)); + root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length)); + } + } + return root; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ08.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ08.java" new file mode 100644 index 0000000..35b88f0 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ08.java" @@ -0,0 +1,47 @@ +// 8. 二叉树的下一个结点 + + +/* +public class TreeLinkNode { + int val; + TreeLinkNode left = null; + TreeLinkNode right = null; + TreeLinkNode next = null; + + TreeLinkNode(int val) { + this.val = val; + } +} +*/ + + +/* +迭代: +1、中序遍历:左中右。根据这个顺序寻找下一个节点 +2、如果二叉树为空,则返回空 +3、如果节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点; +4、如果节点右孩子不存在,则当节点不是根节点时,如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。 + */ +public class Solution { + public TreeLinkNode GetNext(TreeLinkNode pNode) { + if (pNode == null) { + return null; + } + TreeLinkNode node = new TreeLinkNode(0); + if (pNode.right != null) { + node = pNode.right; + while (node.left != null) { + node = node.left; + } + return node; + } + while (pNode.next != null) { + node = pNode.next; + if (node.left == pNode) { + return node; + } + pNode = node; + } + return null; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ09.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ09.java" new file mode 100644 index 0000000..0506add --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ09.java" @@ -0,0 +1,21 @@ +// 9. 用两个栈实现队列 + + +public class Solution { + Stack stack1 = new Stack(); + Stack stack2 = new Stack(); + + public void push(int node) { + while (!stack2.isEmpty()) { + stack1.push(stack2.pop()); + } + stack1.push(node); + while (!stack1.isEmpty()) { + stack2.push(stack1.pop()); + } + } + + public int pop() { + return stack2.pop(); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ10.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ10.java" new file mode 100644 index 0000000..ec25c5c --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ10.java" @@ -0,0 +1,34 @@ +// 10. 斐波那契数列 + + +// 1,1,2,3,5,8,12 +public class Solution { + // 递推 + public int Fibonacci(int n) { + int f0 = 0, f1 = 1; + if (n == 0) { + return f0; + } + if (n == 1) { + return f1; + } + for (int i = 2; i <= n; i++) { + int temp = f0; + f0 = f1; + f1 = temp + f1; + } + return f1; + } + + // 递归 + public int Fibonacci2(int n) { + int f0 = 0, f1 = 1; + if (n == 0) { + return f0; + } + if (n == 1) { + return f1; + } + return Fibonacci(n - 1) + Fibonacci(n - 2); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ11.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ11.java" new file mode 100644 index 0000000..81c7b0b --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ11.java" @@ -0,0 +1,40 @@ +// 11. 旋转数组的最小数字 +// 力扣同题“154. 寻找旋转排序数组中的最小值 II” + +/* +二分查找 + */ +public class Solution { + public int minNumberInRotateArray(int[] array) { + int left = 0, right = array.length - 1; + while (left < right) { + int mid = (left + right) / 2; + if (array[mid] < array[right]) { + right = mid; + } else if (array[mid] > array[right]) { + left = mid + 1; + } else { + right--; + } + } + return array[left]; + } +} + + +/* +第一处出现降序的位置就是最小值 + */ +public class Solution { + public int minNumberInRotateArray(int[] array) { + if (array.length == 0) { + return 0; + } + for (int i = 0; i < array.length - 1; i++) { + if (array[i] > array[i + 1]) { + return array[i + 1]; + } + } + return 0; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ12.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ12.java" new file mode 100644 index 0000000..df4f5e3 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ12.java" @@ -0,0 +1,71 @@ +// 12. 矩阵中的路径 + + +// 新版 +public class Solution { + public boolean hasPath(char[][] matrix, String word) { + char[] words = word.toCharArray(); + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + if (bfs(matrix, words, i, j, 0)) { + return true; + } + } + } + return false; + } + + public boolean bfs(char[][] matrix, char[] words, int i, int j, int index) { + if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || matrix[i][j] != words[index]) { + return false; + } + if (index == words.length - 1) { + return true; + } + char temp = matrix[i][j]; + matrix[i][j] = '.'; + boolean result = bfs(matrix, words, i - 1, j, index + 1) || + bfs(matrix, words, i + 1, j, index + 1) || + bfs(matrix, words, i, j - 1, index + 1) || + bfs(matrix, words, i, j + 1, index + 1); + matrix[i][j] = temp; + return result; + } +} + + +// 旧版 +public class Solution { + public boolean hasPath(char[] matrix, int rows, int cols, char[] str) { + boolean[] flag = new boolean[matrix.length]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (judge(matrix, rows, cols, flag, str, i, j, 0)) { + return true; + } + } + } + return false; + } + + private boolean judge(char[] matrix, int rows, int cols, boolean[] flag, char[] str, int i, int j, int k) { + int index = i * cols + j; + // 不符合的情况 + if (i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index]) { + return false; + } + // 全部匹配完 + if (k == str.length - 1) { + return true; + } + flag[index] = true; + // 判断四个方向是否可行 + boolean res = judge(matrix, rows, cols, flag, str, i - 1, j, k + 1) || // 上 + judge(matrix, rows, cols, flag, str, i + 1, j, k + 1) || // 下 + judge(matrix, rows, cols, flag, str, i, j - 1, k + 1) || // 左 + judge(matrix, rows, cols, flag, str, i, j + 1, k + 1); // 右 + // 回溯还原 + flag[index] = false; + return res; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ13.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ13.java" new file mode 100644 index 0000000..e534fdf --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ13.java" @@ -0,0 +1,30 @@ +// 13. 机器人的运动范围 + + +public class Solution { + ArrayList list = new ArrayList<>(); + + public int movingCount(int threshold, int rows, int cols) { + return stat(threshold, rows, cols, 0, 0); + } + + private int stat(int threshold, int rows, int cols, int row, int col) { + if (row % 10 + row / 10 + col % 10 + col / 10 > threshold) { + return 0; + } + if (row < 0 || row >= rows || col < 0 || col >= cols) { + return 0; + } + String key = row + " " + col; + if (list.contains(key)) { + return 0; + } else { + list.add(key); + } + return 1 + + stat(threshold, rows, cols, row + 1, col) + + stat(threshold, rows, cols, row - 1, col) + + stat(threshold, rows, cols, row, col + 1) + + stat(threshold, rows, cols, row, col - 1); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ14.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ14.java" new file mode 100644 index 0000000..d13bf3c --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ14.java" @@ -0,0 +1,118 @@ +// 14. 剪绳子 + + +/* +动态规划: +1、题目简化:求长度为n的绳子能得到的最大乘积 +2、定义dp数组:dp[i] 表示长度为i的绳子能得到的最大乘积 +3、初始化:dp[0]=1, dp[1]=1 +4、状态转移方程 + 先把长度为i的绳子拆成两部分,一部分是j,另一部分是i-j,那么会有下面4种情况 + 1)j和i-j都不能再拆了 dp[i] = j * (i-j); + 2)j能拆,i-j不能拆 dp[i] = dp[j] * (i-j); + 3)j不能拆,i-j能拆 dp[i] = j * dp[i-j]; + 4)j和i-j都能拆 dp[i] = dp[j] * dp[i-j]; + 取上面4种情况的最大值即可,即两部分在能拆和不能拆时取最大值,然后相乘。由于有多种分段方式,所以多结果再进行比较取最大,整理得到递推公式 + dp[i] = max(dp[i], max(j, dp[j]) * max(i - j, dp[i - j])); +5、遍历dp数组填表 + 1)长度为i的绳子能得到的最大乘积,即dp[i],需要先计算dp[1]到dp[i-1]的值,自底向上计算 + 2)第一个for循环遍历绳子长度,从小到大,从2开始到目标值 + 3)第二个for循环遍历绳子分段后左半部分的长度,遍历到绳子长度一半即可,因为再往后遍历的情况前面已经计算了 +6、返回结果:最后一个状态就是结果 + */ +public class Solution { + public int cutRope (int target) { + int[] dp = new int[target + 1]; + dp[1] = 1; + for (int i = 2; i <= target; i++) { + for (int j = 1; j <= i / 2; j++) { + dp[i] = Math.max(dp[i], Math.max(j, dp[j]) * Math.max(i - j, dp[i - j])); + } + } + return dp[target]; + } +} + + +/* +数学: +1、一个整数先把他分成两部分,x+y=n(假设x>=y并且x-y<=1,也就是说x和y非常接近)那么乘积是x*y。 + 然后我们再把这两部分的差放大(x+1)+(y-1)=n(假设x>=y);他们的乘积是(x+1)*(y-1)=x*y-(x-y)-1,很明显是小于x*y的。 + 所以我们得出结论,如果把整数n分为两部分,那么这两部分的值相差越小乘积越大。 + 同理还可以证明如果分成3部分,4部分……也是相差越小乘积会越大。 +2、如果我们把长度为n的绳子分为x段,则每段只有在长度相等的时候乘积最大,那么每段的长度是n/x。所以他们的乘积是(n/x)^x。 + 我们来对这个函数求导 y=(n/x)^x + 通过对函数求导我们发现,当x=n/e的时候,也就是每段绳子的长度是n/x=n/(n/e)=e的时候乘积最大。 + 我们知道e=2.718281828459。而题中我们的绳子剪的长度都是整数,所以不可能取e,我们只能取接近e的值,也就是3的时候乘积最大。 +3、但也有例外,当n<=4的时候会有特殊情况,因为2*2>1*3 +4、如果n大于4,我们不停的把绳子减去3,并且结果不断乘3,最终结果再乘剩余的target + */ +public class Solution { + public int cutRope (int target) { + if (target == 2 || target == 3) { + return target - 1; + } + int res = 1; + while (target > 4) { + target -= 3; + res *= 3; + } + return res * target; + } +} + + +/* +1、以上解法通过公式直接计算 +2、x表示余数,余1时跟一个3凑成4进行乘积更大,余2时最后乘上即可,余0则刚好等分直接计算 +3、y表示有多少段3 + */ +public class Solution { + public int cutRope(int target) { + if (target == 2 || target == 3) { + return target - 1; + } + int x = target % 3; + int y = target / 3; + if (x == 1) { + return (int) Math.pow(3, y - 1) * 4; + } else if (x == 2) { + return (int) Math.pow(3, y) * 2; + } else { + return (int) Math.pow(3, y); + } + } +} + + +/* +快速幂 + */ +public class Solution { + public int cutRope(int target) { + if (target == 2 || target == 3) { + return target - 1; + } + int x = target % 3; + int y = target / 3; + if (x == 1) { + return pow(3, y - 1) * 4; + } else if (x == 2) { + return pow(3, y) * 2; + } else { + return pow(3, y); + } + } + + private int pow(int base, int num) { + int res = 1; + while (num > 0) { + if ((num & 1) == 1) { + res *= base; + } + base *= base; + num >>= 1; + } + return res; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ15.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ15.java" new file mode 100644 index 0000000..74d3b19 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ15.java" @@ -0,0 +1,35 @@ +// 15. 二进制中1的个数 + + +public class Solution { + public int NumberOf1(int n) { + if (n == 0) return 0; + int num = 0; + while (n != 0) { + num++; + n = n & (n - 1); + } + return num; + } + + // 无符号右移,避免直接右移时负数高位补1 + public int NumberOf1(int n) { + int count = 0; + while (n != 0) { + if ((n & 1) == 1) { + count++; + } + n >>>= 1; + } + return count; + } + + public int NumberOf1(int n) { + char[] ch = Integer.toBinaryString(n).toCharArray(); + int num = 0; + for (char c : ch) { + if (c == '1') num++; + } + return num; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ16.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ16.java" new file mode 100644 index 0000000..52e03df --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ16.java" @@ -0,0 +1,21 @@ +// 16. 数值的整数次方 + + +public class Solution { + public double Power(double base, int exponent) { + if (base == 0) { + return 0; + } + if (exponent == 0) { + return 1; + } + double res = 1; + for (int i = 0; i < Math.abs(exponent); i++) { + res *= base; + } + if (exponent < 0) { + res = 1 / res; + } + return res; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ17.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ17.java" new file mode 100644 index 0000000..6b64c11 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ17.java" @@ -0,0 +1,16 @@ +// 17. 打印从1到最大的n位数 + + +public class Solution { + public int[] printNumbers (int n) { + int count = 0; + for (int i = 0; i < n; i++) { + count = count * 10 + 9; + } + int[] nums = new int[count]; + for (int i = 1; i <= count; i++) { + nums[i - 1] = i; + } + return nums; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ18.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ18.java" new file mode 100644 index 0000000..f59c48e --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ18.java" @@ -0,0 +1,26 @@ +// 18. 删除链表的节点 + + +/* +三个指针定位: +root:指向头节点的指针,用于删除节点后返回新链表头节点 +head:指向当前遍历节点的指针,用于获取节点值 +pre:指向遍历节点的前一节点指针,方便修改下一指针指向,以此删除节点 + */ +public class Solution { + public ListNode deleteNode (ListNode head, int val) { + ListNode root = new ListNode(0); + root.next = head; + ListNode pre = root; + while (head != null) { + if (head.val == val) { + pre.next = head.next; + head.next = null; + break; + } + head = head.next; + pre = pre.next; + } + return root.next; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ19.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ19.java" new file mode 100644 index 0000000..20953b4 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ19.java" @@ -0,0 +1,38 @@ +// 19. 正则表达式匹配 + + +public class Solution { + public boolean match(char[] str, char[] pattern) { + if (str == null || pattern == null) { + return false; + } + int strIndex = 0, patternIndex = 0; + return matchCore(str, strIndex, pattern, patternIndex); + } + + public boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) { + //有效性检验:str到尾,pattern到尾,匹配成功 + if (strIndex == str.length && patternIndex == pattern.length) { + return true; + } + //pattern先到尾,匹配失败 + if (strIndex != str.length && patternIndex == pattern.length) { + return false; + } + //模式第2个是*,且字符串第1个跟模式第1个匹配,分3种匹配模式;如不匹配,模式后移2位 + if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') { + if (strIndex != str.length && (pattern[patternIndex] == str[strIndex] || pattern[patternIndex] == '.')) { + return matchCore(str, strIndex, pattern, patternIndex + 2) //模式后移2,视为x*匹配0个字符 + || matchCore(str, strIndex + 1, pattern, patternIndex + 2) //视为模式匹配1个字符 + || matchCore(str, strIndex + 1, pattern, patternIndex); //*匹配1个,再匹配str中的下一个 + } else { + return matchCore(str, strIndex, pattern, patternIndex + 2); + } + } + //模式第2个不是*,且字符串第1个跟模式第1个匹配,则都后移1位,否则直接返回false + if (strIndex != str.length && (pattern[patternIndex] == str[strIndex] || pattern[patternIndex] == '.')) { + return matchCore(str, strIndex + 1, pattern, patternIndex + 1); + } + return false; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ20.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ20.java" new file mode 100644 index 0000000..06640a5 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ20.java" @@ -0,0 +1,13 @@ +// 20. 表示数值的字符串 + + +public class Solution { + public boolean isNumeric(char[] str) { + try { + Float.parseFloat(new String(str)); + return true; + } catch (Exception e) { + return false; + } + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ21.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ21.java" new file mode 100644 index 0000000..86c77b0 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ21.java" @@ -0,0 +1,24 @@ +// 21. 调整数组顺序使奇数位于偶数前面 + + +public class Solution { + public void reOrderArray(int[] array) { + int len = array.length, l = 0, r = array.length - 1; + int[] res = new int[len]; + for (int i = 0; i < len; i++) { + // 逆序获取偶数,从后往前放入新数组 + if (array[len - i - 1] % 2 == 0) { + res[r] = array[len - i - 1]; + r--; + } + // 顺序获取奇数,从前往后放入新数组 + if (array[i] % 2 == 1) { + res[l] = array[i]; + l++; + } + } + for (int i = 0; i < len; i++) { + array[i] = res[i]; + } + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ22.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ22.java" new file mode 100644 index 0000000..498fa49 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ22.java" @@ -0,0 +1,23 @@ +// 22. 链表中倒数第k个结点 + + +public class Solution { + public ListNode FindKthToTail(ListNode head, int k) { + if (head == null || k == 0) { + return null; + } + ListNode slow = head, fast = head; + for (int i = 1; i < k; i++) { + if (fast.next != null) { + fast = fast.next; + } else { + return null; + } + } + while (fast.next != null) { + fast = fast.next; + slow = slow.next; + } + return slow; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ23.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ23.java" new file mode 100644 index 0000000..f9cbe64 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ23.java" @@ -0,0 +1,36 @@ +// 23. 链表中环的入口结点 + + +public class Solution { + public ListNode EntryNodeOfLoop(ListNode pHead) { + ArrayList list = new ArrayList<>(); + while (pHead != null) { + if (list.contains(pHead.val)) { + return pHead; + } + list.add(pHead.val); + pHead = pHead.next; + } + return null; + } + + public ListNode EntryNodeOfLoop2(ListNode pHead) { + if (pHead == null || pHead.next == null || pHead.next.next == null) { + return null; + } + ListNode node = pHead, slow = pHead.next, fast = pHead.next.next; + while (slow != fast) { + if (slow.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } else { + return null; + } + } + while (node != slow) { + node = node.next; + slow = slow.next; + } + return slow; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ24.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ24.java" new file mode 100644 index 0000000..5367854 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ24.java" @@ -0,0 +1,15 @@ +// 24. 反转链表 + + +public class Solution { + public ListNode ReverseList(ListNode head) { + ListNode pre = null, after = null; + while (head != null) { + after = head.next; + head.next = pre; + pre = head; + head = after; + } + return pre; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ25.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ25.java" new file mode 100644 index 0000000..e794d72 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ25.java" @@ -0,0 +1,21 @@ +// 25. 合并两个排序的链表 + + +public class Solution { + public ListNode Merge(ListNode list1, ListNode list2) { + if (list1 == null) { + return list2; + } else if (list2 == null) { + return list1; + } + ListNode head = null; + if (list1.val < list2.val) { + head = list1; + head.next = Merge(list1.next, list2); + } else { + head = list2; + head.next = Merge(list1, list2.next); + } + return head; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ26.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ26.java" new file mode 100644 index 0000000..cc06e34 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ26.java" @@ -0,0 +1,21 @@ +// 26. 树的子结构 + + +public class Solution { + public boolean HasSubtree(TreeNode root1, TreeNode root2) { + if (root1 == null || root2 == null) { + return false; + } + return IsSubtree(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2); + } + + public boolean IsSubtree(TreeNode root1, TreeNode root2) { + if (root2 == null) { + return true; + } + if (root1 == null || root1.val != root2.val) { + return false; + } + return IsSubtree(root1.left, root2.left) && IsSubtree(root1.right, root2.right); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ27.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ27.java" new file mode 100644 index 0000000..9de58c0 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ27.java" @@ -0,0 +1,30 @@ +// 27. 二叉树的镜像 + + +public class Solution { + public TreeNode Mirror (TreeNode pRoot) { + if (pRoot == null) { + return null; + } + TreeNode temp = pRoot.left; + pRoot.left = pRoot.right; + pRoot.right = temp; + Mirror(pRoot.left); + Mirror(pRoot.right); + return pRoot; + } +} + + +public class Solution { + public TreeNode Mirror (TreeNode pRoot) { + if (pRoot != null) { + TreeNode temp = pRoot.left; + pRoot.left = pRoot.right; + pRoot.right = temp; + Mirror(pRoot.left); + Mirror(pRoot.right); + } + return pRoot; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ28.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ28.java" new file mode 100644 index 0000000..ce3d2e6 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ28.java" @@ -0,0 +1,21 @@ +// 28. 对称的二叉树 + + +public class Solution { + boolean isSymmetrical(TreeNode pRoot) { + if (pRoot == null) { + return true; + } + return isSameTree(pRoot.left, pRoot.right); + } + + boolean isSameTree(TreeNode p, TreeNode q) { + if (p == null && q == null) { + return true; + } + if (p != null && q != null && p.val == q.val) { + return isSameTree(p.left, q.right) && isSameTree(p.right, q.left); + } + return false; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ29.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ29.java" new file mode 100644 index 0000000..a1e41bf --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ29.java" @@ -0,0 +1,86 @@ +// 顺时针打印矩阵 + + +/* +相似题“54.螺旋矩阵”、“59.螺旋矩阵II” + +1、指针视角 + left right + ↓ ↓ + top → 1 2 3 4 + 5 6 7 8 + 9 10 11 12 +bottom → 13 14 15 16 + +2、访问顺序:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 + +3、matrix[行][列]:明确行是谁,列是谁,谁变化 + 顶行:matrix[top][left → right] 不变的是行,变化的是列,列左到右 + 右列:matrix[top → bottom][right] 不变的是列,变化的是行,行上到下 + 底行:matrix[bottom][right → left] 不变的是行,变化的是列,列右到左 + 左列:matrix[bottom → top][left] 不变的是列,变化的是行,行下到上 + +4、此解法最容易理解,算法过程 + 1)先初始化上下左右四个指针 + 2)开始循环遍历,顺时针遍历一圈,每遍历完一行或一列,该行或该列指针向内移动一步,作为新的可遍历边界 + 3)只要 上超过下 或 左超过右,说明已经全部遍历完了,可以结束循环了 + */ +class Solution { + public List printMatrix(int[][] matrix) { + List res = new ArrayList<>(); + int row = matrix.length, col = matrix[0].length; + int top = 0, bottom = row - 1, left = 0, right = col - 1; + while (true) { + for (int i = left; i <= right; i++) { + res.add(matrix[top][i]); + } + top++; + if (top > bottom) break; + + for (int i = top; i <= bottom; i++) { + res.add(matrix[i][right]); + } + right--; + if (left > right) break; + + for (int i = right; i >= left; i--) { + res.add(matrix[bottom][i]); + } + bottom--; + if (top > bottom) break; + + for (int i = bottom; i >= top; i--) { + res.add(matrix[i][left]); + } + left++; + if (left > right) break; + } + return res; + } +} + + +public class Solution { + public ArrayList printMatrix(int[][] matrix) { + int row = matrix.length; + int col = matrix[0].length; + ArrayList ans = new ArrayList<>(); + // 计算循环次数 + int circle = (Math.min(row, col) - 1) / 2 + 1; + for (int i = 0; i < circle; i++) { + // 添加首行 + for (int j = i; j < col - i; j++) + ans.add(matrix[i][j]); + // 添加尾列 + for (int k = i + 1; k < row - i; k++) + ans.add(matrix[k][col - i - 1]); + // 添加尾行 + for (int m = col - i - 2; (m >= i) && (row - i - 1 != i); m--) + ans.add(matrix[row - i - 1][m]); + // 添加尾列 + for (int n = row - i - 2; (n > i) && (col - i - 1 != i); n--) + ans.add(matrix[n][i]); + } + return ans; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ30.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ30.java" new file mode 100644 index 0000000..ef11848 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ30.java" @@ -0,0 +1,31 @@ +// 30. 包含min函数的栈 + + +public class Solution { + Stack stack = new Stack<>(); + + public void push(int node) { + stack.push(node); + } + + public void pop() { + stack.pop(); + } + + public int top() { + return stack.peek(); + } + + public int min() { + int min = stack.peek(); + int temp = 0; + Iterator iterator = stack.iterator(); + while (iterator.hasNext()) { + temp = iterator.next(); + if (temp < min) { + min = temp; + } + } + return min; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ31.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ31.java" new file mode 100644 index 0000000..0119d39 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ31.java" @@ -0,0 +1,21 @@ +// 31. 栈的压入、弹出序列 + + +// 数据入栈,当数据与弹出序列头元素相等时,则数据出栈且序列头元素弹出,重复以上步骤,最终若栈为空则该序列是符合的弹出序列 +public class Solution { + public boolean IsPopOrder(int[] pushA, int[] popA) { + if (pushA.length == 0) { + return false; + } + int index = 0; + Stack stack = new Stack<>(); + for (int num : pushA) { + stack.push(num); + while (!stack.isEmpty() && stack.peek() == popA[index]) { + stack.pop(); + index++; + } + } + return stack.isEmpty(); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ32.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ32.java" new file mode 100644 index 0000000..0950ee9 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ32.java" @@ -0,0 +1,24 @@ +// 32. 从上往下打印二叉树 + + +public class Solution { + public ArrayList PrintFromTopToBottom(TreeNode root) { + ArrayList list = new ArrayList<>(); + if (root == null) { + return list; + } + Queue queue = new LinkedList(); + queue.add(root); + while (!queue.isEmpty()) { + root = queue.poll(); + list.add(root.val); + if (root.left != null) { + queue.add(root.left); + } + if (root.right != null) { + queue.add(root.right); + } + } + return list; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ33.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ33.java" new file mode 100644 index 0000000..d4157e7 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ33.java" @@ -0,0 +1,34 @@ +// 33. 二叉搜索树的后序遍历序列 + + +/* +递归: +1、初始数组为空时,需要返回false +2、递归校验中,数组为空时,需要返回true,所以要拆分成两个方法 + */ +public class Solution { + public boolean VerifySquenceOfBST(int[] sequence) { + if (sequence.length == 0) { + return false; + } + return verify(sequence); + } + + public boolean verify(int[] sequence) { + int len = sequence.length; + if (len < 2) { + return true; + } + int left = 0; + int root = sequence[len - 1]; + while (sequence[left] < root) { + left++; + } + for (int right = left; right < len; right++) { + if (sequence[right] < root) { + return false; + } + } + return verify(Arrays.copyOfRange(sequence, 0, left)) && verify(Arrays.copyOfRange(sequence, left, len - 1)); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ34.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ34.java" new file mode 100644 index 0000000..ee60338 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ34.java" @@ -0,0 +1,38 @@ +// 34. 二叉树中和为某一值的路径(二) + + +/* +回溯: +1、变量作用: + 1)成员变量 list 保存回溯过程产生的子结果 + 2)成员变量 pathList 保存递归到当前节点时路径上的节点值 + 3)局部变量 target 表示到达当前节点后剩余目标值,当剩余0时表示凑到了期望值 +2、递归: + 1)函数作用:累减剩余目标值,将当前节点值加入路径列表,判断剩余目标值是否为0 且 是否为叶结点,若是则将路径列表加入全局列表 + 2)终止条件:节点为空时终止 + 3)递归:左右子节点需要同样的操作,调用同样的方法实现 + 4)回溯:返回到上一层前需要将当前层加入的节点值移除,不影响其他路径递归 + */ +public class Solution { + private ArrayList> list = new ArrayList<>(); + private ArrayList pathList = new ArrayList<>(); + + public ArrayList> FindPath(TreeNode root,int expectNumber) { + backtrack(root, expectNumber); + return list; + } + + private void backtrack(TreeNode root, int target) { + if (root == null) { + return; + } + target -= root.val; + pathList.add(root.val); + if (target == 0 && root.left == null && root.right == null) { + list.add(new ArrayList<>(pathList)); + } + backtrack(root.left, target); + backtrack(root.right, target); + pathList.remove(pathList.size() - 1); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ35.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ35.java" new file mode 100644 index 0000000..c287316 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ35.java" @@ -0,0 +1,25 @@ +// 35. 复杂链表的复制 + + +public class Solution { + public RandomListNode Clone(RandomListNode pHead) { + if (pHead == null) { + return null; + } + HashMap map = new HashMap<>(); + // 复制全部结点 + RandomListNode head = pHead; + while (head != null) { + map.put(head, new RandomListNode(head.label)); + head = head.next; + } + // 连接结点关系 + head = pHead; + while (head != null) { + map.get(head).next = map.get(head.next); + map.get(head).random = map.get(head.random); + head = head.next; + } + return map.get(pHead); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ36.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ36.java" new file mode 100644 index 0000000..4f85630 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ36.java" @@ -0,0 +1,28 @@ +// 36. 二叉搜索树与双向链表 + + +public class Solution { + ArrayList list = new ArrayList<>(); + + public TreeNode Convert(TreeNode pRootOfTree) { + if (pRootOfTree == null) { + return null; + } + midOrder(pRootOfTree); + for (int i = 0; i < list.size() - 1; i++) { + TreeNode pre = list.get(i); + TreeNode after = list.get(i + 1); + pre.right = after; + after.left = pre; + } + return list.get(0); + } + + public void midOrder(TreeNode root) { + if (root != null) { + midOrder(root.left); + list.add(root); + midOrder(root.right); + } + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ37.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ37.java" new file mode 100644 index 0000000..0d573b1 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ37.java" @@ -0,0 +1,31 @@ +// 37. 序列化二叉树 + + +public class Solution { + int index = -1; + + String Serialize(TreeNode root) { + StringBuilder sb = new StringBuilder(); + if (root == null) { + sb.append("#,"); + return sb.toString(); + } + sb.append(root.val + ","); + sb.append(Serialize(root.left)); + sb.append(Serialize(root.right)); + return sb.toString(); + } + + TreeNode Deserialize(String str) { + index++; + String[] splits = str.split(","); + String s = splits[index]; + TreeNode root = null; + if (!s.equals("#")) { + root = new TreeNode(Integer.parseInt(s)); + root.left = Deserialize(str); + root.right = Deserialize(str); + } + return root; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ38.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ38.java" new file mode 100644 index 0000000..2e3b1ce --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ38.java" @@ -0,0 +1,32 @@ +// 38. 字符串的排列 + + +public class Solution { + public ArrayList Permutation(String str) { + ArrayList list = new ArrayList<>(); + if (str.length() != 0) { + TreeSet set = new TreeSet<>(); + backtrack(str.toCharArray(), 0, set); + list.addAll(set); + } + return list; + } + + private void backtrack(char[] array, int begin, TreeSet set) { + if (begin == array.length - 1) { + set.add(String.valueOf(array)); + } else { + for (int i = begin; i < array.length; i++) { + swap(array, begin, i); + backtrack(array, begin + 1, set); + swap(array, begin, i); + } + } + } + + private void swap(char[] array, int x, int y) { + char temp = array[x]; + array[x] = array[y]; + array[y] = temp; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ39.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ39.java" new file mode 100644 index 0000000..bbb101d --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ39.java" @@ -0,0 +1,23 @@ +// 39.数组中出现次数超过一半的数字 + + +public class Solution { + public int MoreThanHalfNum_Solution(int[] array) { + int len = array.length; + if (len == 0) { + return 0; + } + Arrays.sort(array); + int count = 0; + int num = array[len / 2]; + for (int i = 0; i < len; i++) { + if (array[i] == num) { + count++; + } + } + if (count > len / 2) { + return num; + } + return 0; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ40.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ40.java" new file mode 100644 index 0000000..abf9f07 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ40.java" @@ -0,0 +1,16 @@ +// 40. 最小的K个数 + + +public class Solution { + public ArrayList GetLeastNumbers_Solution(int[] input, int k) { + ArrayList list = new ArrayList<>(); + if (k > input.length) { + return list; + } + Arrays.sort(input); + for (int i = 0; i < k; i++) { + list.add(input[i]); + } + return list; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ41.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ41.java" new file mode 100644 index 0000000..e3e3b64 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ41.java" @@ -0,0 +1,52 @@ +// 41. 数据流中的中位数 + + +/* +优先级队列: +1、min表示排序数组的左半部分,从左到右降序排序 + max表示排序数组的右半部分,从左到右升序排序 +2、添加元素的过程 + 1)将元素加入min中 + 2)将min中的最大值,即队头元素弹出加入max + 3)如果min的长度小于max,则平衡长度,将max中的最小值,即队头元素弹出加入min +3、计算中位数,min的队头和max的队头表示整个排序数组的中间位置,直接获取计算 + */ +public class Solution { + private PriorityQueue min = new PriorityQueue<>((o1, o2) -> o2.compareTo(o1)); + private PriorityQueue max = new PriorityQueue<>(); + + public void Insert(Integer num) { + min.offer(num); + max.offer(min.poll()); + if (min.size() < max.size()) { + min.offer(max.poll()); + } + } + + public Double GetMedian() { + if (min.size() > max.size()) { + return (double) min.peek(); + } else { + return (double) (min.peek() + max.peek()) / 2; + } + } +} + + +public class Solution { + ArrayList list = new ArrayList<>(); + + public void Insert(Integer num) { + list.add(num); + Collections.sort(list); + } + + public Double GetMedian() { + int len = list.size(); + if (len % 2 == 0) { + return (double) (list.get(len / 2 - 1) + list.get(len / 2)) / 2; + } else { + return (double) list.get(len / 2); + } + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ42.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ42.java" new file mode 100644 index 0000000..a848a41 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ42.java" @@ -0,0 +1,50 @@ +// 42. 连续子数组的最大和 + + +/* +动态规划: +1、题目简化:求连续子数组最大和 +定义dp数组:dp[i] 表示以索引i结尾的连续子数组的最大和 +2、初始化:dp[0] = array[0] 表示首元素结尾的最大和是对应元素值 +3、状态转移方程 + 1)每次遇到一个新元素,如果前面的连续子数组如果为正数,能提供收益,那么加上后当前元素结尾的连续子数组会变得更大, + 如果前面的连续子数组如果为负数,不能提供收益,那么直接丢弃,单独它本身会更大 + 2)dp[i] = Math.max(dp[i - 1] + array[i], array[i]) +4、遍历dp数组填表:从索引1开始遍历,根据状态转移方程填表 +5、返回结果:最大的状态就是结果 + */ +public class Solution { + public int FindGreatestSumOfSubArray(int[] array) { + int n = array.length; + int[] dp = new int[n]; + dp[0] = array[0]; + for (int i = 1; i < n; i++) { + dp[i] = Math.max(dp[i - 1] + array[i], array[i]); + } + return Arrays.stream(dp).max().getAsInt(); + } +} + + +/* +贪心 + */ +public class Solution { + public int FindGreatestSumOfSubArray(int[] array) { + int maxNum = Arrays.stream(array).max().getAsInt(); + if (maxNum < 0) { + return maxNum; + } + int maxSum = 0, curSum = 0; + for (int i = 0; i < array.length; i++) { + curSum += array[i]; + if (curSum > maxSum) { + maxSum = curSum; + } + if (curSum < 0) { + curSum = 0; + } + } + return maxSum; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ43.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ43.java" new file mode 100644 index 0000000..6824123 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ43.java" @@ -0,0 +1,19 @@ +// 43. 整数中1出现的次数(从1到n整数中1出现的次数) + + +public class Solution { + public int NumberOf1Between1AndN_Solution(int n) { + int count = 0; + while (n > 0) { + String num = String.valueOf(n); + char[] array = num.toCharArray(); + for (char c : array) { + if (c == '1') { + count++; + } + } + n--; + } + return count; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ44.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ44.java" new file mode 100644 index 0000000..f79c87c --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ44.java" @@ -0,0 +1,38 @@ +// 44. 数字序列中某一位的数字 + + +/* +1、变量含义 + 1)digit:每个数字的位数 + 2)low:相同位数数字的区间起始值 + 3)high:相同位数数字的区间终止值 + 4)count:相同位数数字的区间内数字个数 +2、算法过程 + 1)初始化变量 + 2)确定第n位所在的数字区间 + 3)确定第n位实际对应的数字,即区间起始值加偏移个数 + 4)确定对应数字的第几位,即偏移位数 + + 区间 每个数字位数digit 总位数count n + 0到9 [0,10) 1 10 897 + 10到99 [10,100) 2 180 887 +100到999 [100,1000) 3 2700 707 +num = 100 + 707/3 = 335 +offset = 707 % 3 = 2 + */ +public class Solution { + public int findNthDigit (int n) { + int digit = 1; + long low = 0, high = 10, count = 10; + while (n > count) { + n -= count; + low = high; + high *= 10; + digit++; + count = (high - low) * digit; + } + int num = low + n / digit; + int offset = n % digit; + return String.valueOf(num).charAt(offset) - '0'; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ45.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ45.java" new file mode 100644 index 0000000..a5f2bd1 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ45.java" @@ -0,0 +1,25 @@ +// 45. 把数组排成最小的数 + + +public class Solution { + public String PrintMinNumber(int[] numbers) { + List list = new ArrayList(); + for (int i : numbers) { + list.add(i); + } + Collections.sort(list, new Comparator() { + // 返回负数则第一个参数放在前面,正数或零则第一个参数放在后面 + @Override + public int compare(Integer o1, Integer o2) { + String str1 = o1 + "" + o2; + String str2 = o2 + "" + o1; + return str1.compareTo(str2); + } + }); + StringBuilder sb = new StringBuilder(); + for (Integer i : list) { + sb.append(i); + } + return sb.toString(); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ46.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ46.java" new file mode 100644 index 0000000..c35d211 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ46.java" @@ -0,0 +1,44 @@ +// 46. 把数字翻译成字符串 + + +/* +动态规划: +1、先排除几种特殊情况 + 1)排除0,无法译码 + 2)排除只有一种可能的10和20 + 3)排除当0的前面不是1或2时,无法译码 +2、定义dp数组:dp[i] 表示前i个字符的译码方式数 +3、初始化:填表为1,表示每个字符的译码方式数为1 +4、状态转移方程 + 1)对于一个字符,如果直接译码,则dp[i] = dp[i - 1];如果组合译码,则dp[i] = dp[i - 2] + 2)当前字符与前一字符构成 11-19 21-26时,有两种译码方式,则dp[i] = dp[i - 1] + dp[i - 2] + 否则只有一种译码方式,则dp[i] = dp[i - 1] +5、遍历dp数组填表:一个for循环遍历dp数组,根据状态转移方程填表 +6、返回结果:最后一个状态就是结果 + */ +public class Solution { + public int solve (String nums) { + if ("0".equals(nums)) { + return 0; + } + if (nums == "10" || nums == "20") { + return 1; + } + int n = nums.length(); + for (int i = 1; i < n; i++) { + if (nums.charAt(i) == '0' && nums.charAt(i - 1) != '1' && nums.charAt(i - 1) != '2') { + return 0; + } + } + int[] dp = new int[n + 1]; + Arrays.fill(dp, 1); + for (int i = 2; i <= n; i++) { + if ((nums.charAt(i - 2) == '1' && nums.charAt(i - 1) != '0') || (nums.charAt(i - 2) == '2' && nums.charAt(i - 1) >= '1' && nums.charAt(i - 1) <= '6')) { + dp[i] = dp[i - 1] + dp[i - 2]; + } else { + dp[i] = dp[i - 1]; + } + } + return dp[n]; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ47.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ47.java" new file mode 100644 index 0000000..5f82853 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ47.java" @@ -0,0 +1,51 @@ +// 47. 礼物的最大价值 + + +// 64. 最小路径和(力扣,思路相同,本题是 最大路径和) +/* +1、题目简化:求从 (0,0) 到达 (m-1,n-1) 位置的最大路径和 +2、定义dp数组:本题可以直接在原数组操作。grid[i][j] 表示到达 (i,j) 位置的最大路径和 +3、初始化: + 1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化 + 2)首行首列的路径和进行累加初始化 +4、状态转移方程:grid[i][j] += Math.max(grid[i - 1][j], grid[i][j - 1]); 即上方或左方的最大路径和 +5、遍历顺序:两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最大路径和并填表,直到终点,获得结果 + */ +class Solution { + public int minPathSum(int[][] grid) { + int n = grid.length, m = grid[0].length; + for (int i = 1; i < n; i++) { + grid[i][0] += grid[i - 1][0]; + } + for (int j = 1; j < m; j++) { + grid[0][j] += grid[0][j - 1]; + } + for (int i = 1; i < n; i++) { + for (int j = 1; j < m; j++) { + grid[i][j] += Math.max(grid[i - 1][j], grid[i][j - 1]); + } + } + return grid[n - 1][m - 1]; + } +} + + +public class Solution { + public int maxValue (int[][] grid) { + int m = grid.length, n = grid[0].length; + int[][] dp = new int[m][n]; + dp[0][0] = grid[0][0]; + for (int i = 1; i < m; i++) { + dp[i][0] = dp[i - 1][0] + grid[i][0]; + } + for (int j = 1; j < n; j++) { + dp[0][j] = dp[0][j - 1] + grid[0][j]; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; + } + } + return dp[m - 1][n - 1]; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ48.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ48.java" new file mode 100644 index 0000000..1c06e59 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ48.java" @@ -0,0 +1,55 @@ +// 48. 最长不含重复字符的子字符串 +//同“3. 无重复字符的最长子串”(力扣) + + +/* +索引定位收缩左区间: +1、HashMap保存滑动窗口中的字符的索引 +2、如果右指针移动过程新的字符 出现 在滑动窗口中,则更新左指针位置 +3、更新当前字符在HashMap中的索引 +4、右指针每移动一次后,计算新窗口的长度,比较并保存最大长度 + */ +public class Solution { + public int lengthOfLongestSubstring (String s) { + int maxLen = 0, start = 0; + Map map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (map.containsKey(c)) { + start = Math.max(start, map.get(c) + 1); + } + map.put(c, i); + maxLen = Math.max(maxLen, i - start + 1); + } + return maxLen; + } +} + + +/* +左指针右移收缩左区间: +1、HashMap保存滑动窗口中的字符的出现次数 +2、如果右指针移动过程新的字符 没有 在滑动窗口中,则将字符添加到HashMap中,次数记为1 +3、如果右指针移动过程新的字符 出现 在滑动窗口中,则移动左指针直到同样该字符的下一位,移动过程指向的字符在HashMap中出现次数减1 +4、右指针每移动一次后,计算新窗口的长度,比较并保存最大长度 + */ +class Solution { + public int lengthOfLongestSubstring(String s) { + int maxLen = 0, start = 0; + Map map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (map.getOrDefault(c, 0) == 0) { + map.put(c, 1); + } else { + while (s.charAt(start) != c) { + map.put(s.charAt(start), map.get(s.charAt(start)) - 1); + start++; + } + start++; + } + maxLen = Math.max(maxLen, i - start + 1); + } + return maxLen; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ49.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ49.java" new file mode 100644 index 0000000..36855b0 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ49.java" @@ -0,0 +1,27 @@ +// 49. 丑数 + + +public class Solution { + public int GetUglyNumber_Solution(int index) { + if (index == 0) { + return 0; + } + int[] array = new int[index]; + array[0] = 1; + int t2 = 0, t3 = 0, t5 = 0, count = 0; + while (count < index - 1) { + int num = Math.min(Math.min(array[t2] * 2, array[t3] * 3), array[t5] * 5); + array[++count] = num; + if (num % 2 == 0) { + t2++; + } + if (num % 3 == 0) { + t3++; + } + if (num % 5 == 0) { + t5++; + } + } + return array[index - 1]; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ50.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ50.java" new file mode 100644 index 0000000..a7e2b5d --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ50.java" @@ -0,0 +1,42 @@ +// 50. 第一个只出现一次的字符 + + +public class Solution { + // 数组实现 + public int FirstNotRepeatingChar(String str) { + int[] array = new int[256]; + char[] chars = str.toCharArray(); + // 先统计全部字符个数 + for (int i = 0; i < str.length(); i++) { + array[chars[i]]++; + } + // 再判断第一个出现一次的字符 + for (int i = 0; i < str.length(); i++) { + if (array[chars[i]] == 1) { + return i; + } + } + return -1; + } + + // 字典实现 + public int FirstNotRepeatingChar2(String str) { + LinkedHashMap map = new LinkedHashMap(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (map.containsKey(c)) { + int time = map.get(c); + map.put(c, ++time); + } else { + map.put(c, 1); + } + } + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (map.get(c) == 1) { + return i; + } + } + return -1; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ51.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ51.java" new file mode 100644 index 0000000..9650275 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ51.java" @@ -0,0 +1,45 @@ +// 51. 数组中的逆序对 + + +public class Solution { + private int count; + + public int InversePairs(int[] array) { + mergeSort(array, 0, array.length - 1); + return count; + } + + private void mergeSort(int[] arr, int left, int right) { + if (left >= right) { + return; + } + int mid = (left + right) / 2; + mergeSort(arr, left, mid); + mergeSort(arr, mid + 1, right); + merge(arr, left, mid, right); + } + + private void merge(int[] arr, int left, int mid, int right) { + int[] temp = new int[right - left + 1]; + int index = 0; + int p1 = left; + int p2 = mid + 1; + while (p1 <= mid && p2 <= right) { + if (arr[p1] <= arr[p2]) { + temp[index++] = arr[p1++]; + } else { + temp[index++] = arr[p2++]; + count = (count + (mid - p1 + 1)) % 1000000007; + } + } + while (p1 <= mid) { + temp[index++] = arr[p1++]; + } + while (p2 <= right) { + temp[index++] = arr[p2++]; + } + for (int i = 0; i < temp.length; i++) { + arr[left + i] = temp[i]; + } + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ52.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ52.java" new file mode 100644 index 0000000..628d9bf --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ52.java" @@ -0,0 +1,13 @@ +// 52. 两个链表的第一个公共结点 + + +public class Solution { + public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { + ListNode p1 = pHead1, p2 = pHead2; + while (p1 != p2) { + p1 = p1 != null ? p1.next : pHead2; + p2 = p2 != null ? p2.next : pHead1; + } + return p1; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ53.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ53.java" new file mode 100644 index 0000000..cc186cd --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ53.java" @@ -0,0 +1,21 @@ +// 53. 数字在排序数组中出现的次数 + + +public class Solution { + public int GetNumberOfK(int[] array , int k) { + int count = 0; + for (int i = 0; i < array.length; i++) { + if (array[i] == k) { + for (int j = i; j < array.length; j++) { + if (array[j] == k) { + count++; + } else { + break; + } + } + break; + } + } + return count; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ54.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ54.java" new file mode 100644 index 0000000..0067319 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ54.java" @@ -0,0 +1,64 @@ +// 54. 二叉搜索树的第k个结点 + + +/* +中序遍历保存到数组,取第k个元素 + */ +public class Solution { + private ArrayList list = new ArrayList<>(); + + public int KthNode (TreeNode proot, int k) { + if (proot == null || k == 0) { + return -1; + } + inOrder(proot); + if (k > list.size()) { + return -1; + } + return list.get(k - 1); + } + + private void inOrder(TreeNode root) { + if (root == null) { + return; + } + inOrder(root.left); + list.add(root.val); + inOrder(root.right); + } +} + + +/* +1、方法功能:入参是 一个节点 和 目标节点位号,遍历找出并返回目标节点,没有则返回空 +2、终止条件:节点为空时,返回空 +3、一个节点处理过程和返回结果:累加位号,如果等于目标节点位号则返回该节点,否则返回空 +4、递归调用:左右节点同样需要寻找判断是否目标节点,因此调用同样的方法 +5、递归顺序:中序遍历,可以从小到大遍历节点 +6、使用递归调用结果和返回结果: + 1)左节点递归结果不为空时,说明找到了目标节点,返回该结果,否则继续判断根节点 + 2)累加位号,如果等于目标节点位号则返回该节点,否则继续判断右节点 + 3)右节点递归结果不为空时,说明找到了目标节点,返回该结果。否则说明没有目标位号的节点,返回空 + */ +public class Solution { + int count = 0; + + TreeNode KthNode(TreeNode pRoot, int k) { + if (pRoot == null) { + return null; + } + TreeNode node = KthNode(pRoot.left, k); + if (node != null) { + return node; + } + count++; + if (count == k) { + return pRoot; + } + node = KthNode(pRoot.right, k); + if (node != null) { + return node; + } + return null; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ55.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ55.java" new file mode 100644 index 0000000..84caed4 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ55.java" @@ -0,0 +1,11 @@ +// 55. 二叉树的深度 + + +public class Solution { + public int TreeDepth(TreeNode root) { + if (root == null) { + return 0; + } + return 1 + Math.max(TreeDepth(root.left), TreeDepth(root.right)); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ56.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ56.java" new file mode 100644 index 0000000..788138d --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ56.java" @@ -0,0 +1,63 @@ +// 56. 数组中只出现一次的两个数字 + + +/* +集合:用HashSet存放元素,存在则移除,不存在则添加,最终只剩下出现一次的数字,遍历集合元素加到数组,最后数组排序 + */ +public class Solution { + public int[] FindNumsAppearOnce (int[] array) { + int[] res = new int[2]; + Set set = new HashSet<>(); + for (int i = 0; i < array.length; i++) { + if (set.contains(array[i])) { + set.remove(array[i]); + } else { + set.add(array[i]); + } + } + int i = 0; + for (Integer num : set) { + res[i++] = num; + } + Arrays.sort(res); + return res; + } +} + + +/* +异或运算: +1、异或公式 + 1)一个数和 0 做 XOR 运算等于本身:a⊕0 = a + 2)一个数和其本身做 XOR 运算等于 0:a⊕a = 0 + 3)XOR 运算满足交换律和结合律:a⊕b⊕a = (a⊕a)⊕b = 0⊕b = b +2、先将整个数组元素进行异或运算,结果是 只出现一次的两个数字的异或运算结果 +3、对两个数字的异或结果进行1的与运算,从最低位开始找,找到二进制位首个两者不同的位置 +4、对所有数进行分组并异或运算,最终得到两个数字 +5、存入结果数组,并排序 + */ +public class Solution { + public int[] FindNumsAppearOnce (int[] array) { + int temp = 0; + for (int num : array) { + temp ^= num; + } + int mask = 1; + while ((temp & mask) == 0) { + mask <<= 1; + } + int x = 0, y = 0; + for (int num : array) { + if ((num & mask) == 0) { + x ^= num; + } else { + y ^= num; + } + } + int[] res = new int[2]; + res[0] = x; + res[1] = y; + Arrays.sort(res); + return res; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ57.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ57.java" new file mode 100644 index 0000000..4f784ba --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ57.java" @@ -0,0 +1,21 @@ +// 57. 和为S的两个数字 + + +public class Solution { + public ArrayList FindNumbersWithSum(int[] array, int sum) { + ArrayList list = new ArrayList<>(); + int left = 0, right = array.length-1; + while (left < right) { + if (array[left] + array[right] > sum) { + right--; + } else if (array[left] + array[right] < sum) { + left++; + } else { + list.add(array[left]); + list.add(array[right]); + return list; + } + } + return list; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ58.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ58.java" new file mode 100644 index 0000000..255925f --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ58.java" @@ -0,0 +1,12 @@ +// 58. 左旋转字符串 + + +public class Solution { + public String LeftRotateString(String str, int n) { + int len = str.length(); + if (n > len) { + return str; + } + return str.substring(n, len) + str.substring(0, n); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ59.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ59.java" new file mode 100644 index 0000000..1cda2ea --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ59.java" @@ -0,0 +1,31 @@ +// 59. 滑动窗口的最大值 +// 同力扣“239. 滑动窗口最大值” + +/* +单调递减队列,左头右尾 + */ +public class Solution { + public ArrayList maxInWindows(int[] num, int size) { + ArrayList list = new ArrayList<>(); + if (num.length == 0 || size == 0 || size > num.length) { + return list; + } + LinkedList queue = new LinkedList<>(); + for (int i = 0; i < num.length; i++) { + // 去掉比当前值小的值 + while (!queue.isEmpty() && num[i] > num[queue.peekLast()]) { + queue.pollLast(); + } + queue.addLast(i); + // 判断队首元素是否不在窗口内 + if (queue.peekFirst() == i - size) { + queue.pollFirst(); + } + // 添加当前窗口的最大值 + if (i >= size - 1) { + list.add(num[queue.peekFirst()]); + } + } + return list; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ61.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ61.java" new file mode 100644 index 0000000..548448f --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ61.java" @@ -0,0 +1,35 @@ +// 60. 扑克牌顺子 + + +public class Solution { + public boolean isContinuous(int[] numbers) { + if (numbers.length < 5) { + return false; + } + ArrayList list = new ArrayList<>(); + int minNum = 99, maxNum = -1; + for (int i = 0; i < 5; i++) { + Integer num = numbers[i]; + // 去掉0 + if (num != 0) { + // 牌重复 + if (list.contains(num)) { + return false; + } + list.add(num); + // 记录最小和最大的牌 + if (num < minNum) { + minNum = num; + } + if (num > maxNum) { + maxNum = num; + } + } + } + // 相差小于5就是顺子 + if (maxNum - minNum < 5) { + return true; + } + return false; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ62.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ62.java" new file mode 100644 index 0000000..ccd2d55 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ62.java" @@ -0,0 +1,51 @@ +// 62. 孩子们的游戏(圆圈中最后剩下的数) + + +/* +1、变量含义 + 1)人数:n + 2)随机数:m + 3)小朋友编号:number + 4)报数:step + 5)剩余人数:count + 6)出列标记:array +2、排除无效情况 +3、剩余人数不为0时,循环遍历 + 1)编号累加 + 2)编号超过人数时,编号归零 + 3)对应编号已出列则跳过 + 4)有效编号则报数累加 + 5)报数等于随机数时,编号出列,报数归零,剩余人数减1 +4、最后一个出列的编号即结果 + */ +public class Solution { + public int LastRemaining_Solution(int n, int m) { + if (n < 1 || m < 1) { + return -1; + } + int[] array = new int[n]; + // 编号,报数,剩余人数 + int number = -1, step = 0, count = n; + while (count > 0) { + number++; + // 模拟环,编号重新开始 + if (number >= n) { + number = 0; + } + // 跳过已出列 + if (array[number] == -1) { + continue; + } + step++; + if (step == m) { + // 出列 + array[number] = -1; + // 重新报数 + step = 0; + // 剩余人数减1 + count--; + } + } + return number; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ63.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ63.java" new file mode 100644 index 0000000..27634b6 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ63.java" @@ -0,0 +1,98 @@ +// 63. 买卖股票的最好时机(一) +// 121. 买卖股票的最佳时机(力扣) + + +/* +动态规划: +1、定义dp数组: + dp[i][0] 表示第i天交易结束后不持有股票的最大利润 + dp[i][1] 表示第i天交易结束后持有股票的最大利润 +2、初始化 + dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略 + dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0] +3、状态转移方程 + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); + 第i天不持有股票 前一天不持有股票 前一天持有股票且今天卖出 + dp[i][1] = Math.max(dp[i - 1][1], -prices[i]); // 注意:只能买卖一次,所以买入时的利润为-prices[i] + 第i天持有股票 前一天持有股票 今天买入 +4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:最后一个不持有股票的状态就是结果 + +二维dp数组更新过程 +prices = [7,1,5,3,6,4] +0 -7 +0 -1 +4 -1 +4 -1 +5 -1 +5 -1 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[][] dp = new int[n][2]; + dp[0][0] = 0; + dp[0][1] = -prices[0]; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); + dp[i][1] = Math.max(dp[i - 1][1], -prices[i]); + } + return dp[n - 1][0]; + } +} + + +/* +动态规划思路: +1、定义dp数组:dp[i]表示第i天交易结束后可获得的最大利润(天数从0开始,与索引对应,方便理解) +2、状态转移方程:dp[i] = Math.max(dp[i - 1], prices[i] - minPrice) + 第i-1天可获得的最大利润 第i天卖出可获得的最大利润 +3、初始化:dp[0] = 0,第0天的最大利润为0 +4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果 +5、返回结果:最后一个状态就是结果 + */ +class Solution { + public int maxProfit(int[] prices) { + int n = prices.length; + int[] dp = new int[n]; + dp[0] = 0; + int minPrice = prices[0]; + for (int i = 1; i < n; i++) { + minPrice = Math.min(minPrice, prices[i]); + dp[i] = Math.max(dp[i - 1], prices[i] - minPrice); + } + return dp[n - 1]; + } +} + + +/* +思路: +1、动态规划维护的dp数组,存放的每个元素只用一次就不需要了,因此可以直接用一个变量来表示利润最大值 +2、遍历列表,计算到当天为止的价格最小值、利润最大值 + */ +public class Solution { + public int maxProfit (int[] prices) { + int n = prices.length; + if (n < 2) { + return 0; + } + int minPrice = prices[0], profit = 0; + for (int i = 1; i < n; i++) { + profit = Math.max(profit, prices[i] - minPrice); + minPrice = Math.min(minPrice, prices[i]); + } + return profit; + } +} + +class Solution { + public int maxProfit(int[] prices) { + int minPrice = 99999, maxProfit = 0; + for (int price : prices) { + minPrice = Math.min(minPrice, price); + maxProfit = Math.max(maxProfit, price - minPrice); + } + return maxProfit; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ64.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ64.java" new file mode 100644 index 0000000..2cfb562 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ64.java" @@ -0,0 +1,11 @@ +// 64. 求1+2+3+...+n + + +public class Solution { + public int Sum_Solution(int n) { + if (n == 0) { + return 0; + } + return n + Sum_Solution(n - 1); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ65.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ65.java" new file mode 100644 index 0000000..4138d78 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ65.java" @@ -0,0 +1,10 @@ +// 65. 不用加减乘除做加法 + + +public class Solution { + public int Add(int num1, int num2) { + BigInteger b1 = new BigInteger(String.valueOf(num1)); + BigInteger b2 = new BigInteger(String.valueOf(num2)); + return b1.add(b2).intValue(); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ66.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ66.java" new file mode 100644 index 0000000..4c2d498 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ66.java" @@ -0,0 +1,18 @@ +// 66. 构建乘积数组 + + +public class Solution { + public int[] multiply(int[] A) { + int n = A.length; + int[] B = new int[n]; + Arrays.fill(B, 1); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (i != j) { + B[i] *= A[j]; + } + } + } + return B; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ67.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ67.java" new file mode 100644 index 0000000..4fd8852 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ67.java" @@ -0,0 +1,41 @@ +// 67. 把字符串转换成整数(atoi) + + +/* +1、遍历去掉空格 +2、判断是否有+-符号,有则记录sign +3、遍历数字,如果算上当前数字后超过整型最大值,则根据sign标志直接返回结果,否则更新结果将当前数字加入最低位 + if语句另一写法 if ((long) res * 10 + digit > Integer.MAX_VALUE) {} +4、根据sign标志返回结果 + */ +class Solution { + public int myAtoi(String s) { + int n = s.length(), res = 0, index = 0, sign = 1; + char[] array = s.toCharArray(); + while (index < n && array[index] == ' ') { + index++; + } + if (index < n && (array[index] == '-' || array[index] == '+')) { + sign = array[index++] == '-' ? -1 : 1; + } + while (index < n && array[index] >= '0' && array[index] <= '9') { + int digit = array[index++] - '0'; + if (res > (Integer.MAX_VALUE - digit) / 10) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + res = res * 10 + digit; + } + return res * sign; + } +} + + +public class Solution { + public int StrToInt(String str) { + try { + return Integer.valueOf(str); + } catch (Exception e) { + return 0; + } + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ68.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ68.java" new file mode 100644 index 0000000..63ace42 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ68.java" @@ -0,0 +1,78 @@ +// 68. 二叉搜索树的最近公共祖先 + + +/* +递归: +1、随便给2个数,利用二叉搜索树的性质: + 1)如果两个值都小于根节点,说明公共祖先在左子树一侧 + 2)如果两个值都大于根节点,说明公共祖先在右子树一侧 + 3)如果根节点的值恰好在两个给定值之间,或者根节点的值等于其中一个给定值,这个根节点就是最近的公共祖先 +2、函数功能:在节点中找p、q。有两种情况才会返回 + 1)直接找到了p或q,返回该节点值 + 2)p和q分别在左右子树,返回根节点值 +3、return root.val; 省略了if条件,即 p <= root <= q 或 q <= root <= p, + + root p q + / \ / \ / \ + p q x q x p + p q + / \ / \ + q x p x + */ +public class Solution { + public int lowestCommonAncestor (TreeNode root, int p, int q) { + if (root.val < p && root.val < q) { + return lowestCommonAncestor(root.right, p, q); + } else if (root.val > p && root.val > q) { + return lowestCommonAncestor(root.left, p, q); + } else { + return root.val; + } + } +} + + +/* +迭代 + */ +public class Solution { + public int lowestCommonAncestor (TreeNode root, int p, int q) { + while (true) { + if (root.val < p && root.val < q) { + root = root.right; + } else if (root.val > p && root.val > q) { + root = root.left; + } else { + return root.val; + } + } + } +} + + +/* +思路同剑指“86. 在二叉树中找到两个节点的最近公共祖先”、力扣“236. 二叉树的最近公共祖先” +1、不利用二叉搜索树性质,直接当成普通二叉树进行节点遍历 +2、函数功能:在节点中找p、q,找不到返回-1,找到了返回该节点值 不继续往下找了 +3、递归逻辑: + 1)根节点找不到时,要再判断左右节点能否找到,因此调用递归函数得到左右节点寻找结果 + 2)拿结果做判断,如果左右都能找到,说明p、q在左右两边,当前根节点是最近公共祖先,返回根节点值 + 3)如果左边找到了,右边没找到,说明p、q都在左边,左边的节点值是最近公共祖先 + 如果右边找到了,左边没找到,说明p、q都在右边,右边的节点值是最近公共祖先 + */ +public class Solution { + public int lowestCommonAncestor (TreeNode root, int p, int q) { + if (root == null) { + return -1; + } + if (root.val == p || root.val == q) { + return root.val; + } + int left = lowestCommonAncestor(root.left, p, q); + int right = lowestCommonAncestor(root.right, p, q); + if (left != -1 && right != -1) { + return root.val; + } + return left != -1 ? left : right; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ69.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ69.java" new file mode 100644 index 0000000..d839d44 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ69.java" @@ -0,0 +1,15 @@ +// 69. 跳台阶 + + +// f(1)=1 f(2)=2 f(3)=3 f(4)=5 f(5)=8 +public class Solution { + public int JumpFloor(int target) { + int a = 1, b = 1; + for (int i = 0; i < target; i++) { + int temp = a; + a = b; + b += temp; + } + return a; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ70.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ70.java" new file mode 100644 index 0000000..57ec6b4 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ70.java" @@ -0,0 +1,18 @@ +// 70. 矩形覆盖 + + +// 类似斐波那契数列:f(1)=1 f(2)=2 f(3)=3 f(4)=5 +public class Solution { + public int RectCover(int target) { + int a = 0, b = 1; + if (target == 0) { + return 0; + } + for (int i = 0; i < target; i++) { + int temp = a; + a = b; + b += temp; + } + return b; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ71.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ71.java" new file mode 100644 index 0000000..f4aa23e --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ71.java" @@ -0,0 +1,14 @@ +// 71. 变态跳台阶 + + +// f(1)=1 f(2)=2 f(3)=4 f(4)=8 +// f(n)=2的n-1次方 +public class Solution { + public int JumpFloorII(int target) { + int res = 1; + for (int i = 1; i < target; i++) { + res *= 2; + } + return res; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ73.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ73.java" new file mode 100644 index 0000000..3c3f217 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ73.java" @@ -0,0 +1,19 @@ +// 73. 翻转单词顺序列 + + +public class Solution { + public String ReverseSentence(String str) { + if (str == null) { + return null; + } + if (str.trim().equals("")) { + return str; + } + String[] array = str.split(" "); + String res = ""; + for (int i = array.length - 1; i >= 0; i--) { + res = res + array[i] + " "; + } + return res.trim(); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ74.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ74.java" new file mode 100644 index 0000000..201a321 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ74.java" @@ -0,0 +1,26 @@ +// 74. 和为S的连续正数序列 + + +public class Solution { + public ArrayList> FindContinuousSequence(int sum) { + ArrayList> res = new ArrayList<>(); + for (int i = 1; i < sum; i++) { + int num = i; + for (int j = i + 1; j < sum; j++) { + num += j; + if (num < sum) { + continue; + } else if (num == sum) { + ArrayList list = new ArrayList<>(); + for (int k = i; k <= j; k++) { + list.add(k); + } + res.add(list); + } else { + break; + } + } + } + return res; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ75.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ75.java" new file mode 100644 index 0000000..6b09fb0 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ75.java" @@ -0,0 +1,22 @@ +// 75. 字符流中第一个不重复的字符 + + +public class Solution { + int[] array = new int[256]; + StringBuilder sb = new StringBuilder(); + + public void Insert(char ch) { + array[ch]++; + sb.append(ch); + } + + public char FirstAppearingOnce() { + String str = sb.toString(); + for (int i = 0; i < str.length(); i++) { + if (array[str.charAt(i)] == 1) { + return str.charAt(i); + } + } + return '#'; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ76.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ76.java" new file mode 100644 index 0000000..a9bcb71 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ76.java" @@ -0,0 +1,25 @@ +// 76. 删除链表中重复的结点 + + +public class Solution { + public ListNode deleteDuplication(ListNode pHead) { + if (pHead == null) { + return null; + } + ListNode root = new ListNode(0); + root.next = pHead; + ListNode pre = root, last = root.next; + while (last != null) { + if (last.next != null && last.val == last.next.val) { + while (last.next != null && last.val == last.next.val) { + last = last.next; + } + pre.next = last.next; + } else { + pre = pre.next; + } + last = last.next; + } + return root.next; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ77.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ77.java" new file mode 100644 index 0000000..6bf123c --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ77.java" @@ -0,0 +1,35 @@ +// 77. 按之字形顺序打印二叉树 + + +public class Solution { + public ArrayList> Print(TreeNode pRoot) { + ArrayList> res = new ArrayList<>(); + if (pRoot == null) { + return res; + } + Queue queue = new LinkedList<>(); + queue.add(pRoot); + boolean flag = false; + while (queue.size() != 0) { + int len = queue.size(); + ArrayList list = new ArrayList<>(); + while (len > 0) { + TreeNode node = queue.poll(); + list.add(node.val); + if (node.left != null) { + queue.add(node.left); + } + if (node.right != null) { + queue.add(node.right); + } + len--; + } + if (flag) { + Collections.reverse(list); + } + res.add(list); + flag = !flag; + } + return res; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ78.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ78.java" new file mode 100644 index 0000000..8ebfaec --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ78.java" @@ -0,0 +1,42 @@ +// 78. 把二叉树打印成多行 + + +/* +public class TreeNode { + int val = 0; + TreeNode left = null; + TreeNode right = null; + + public TreeNode(int val) { + this.val = val; + } +}*/ + + +public class Solution { + ArrayList> Print(TreeNode pRoot) { + ArrayList> res = new ArrayList<>(); + if (pRoot == null) { + return res; + } + Queue queue = new LinkedList<>(); + queue.add(pRoot); + while (queue.size() != 0) { + int len = queue.size(); + ArrayList list = new ArrayList<>(); + while (len > 0) { + TreeNode node = queue.poll(); + list.add(node.val); + if (node.left != null) { + queue.add(node.left); + } + if (node.right != null) { + queue.add(node.right); + } + len--; + } + res.add(list); + } + return res; + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ79.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ79.java" new file mode 100644 index 0000000..c09d0f7 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ79.java" @@ -0,0 +1,18 @@ +// 79. 判断是不是平衡二叉树 +// 同力扣“110. 平衡二叉树” + +public class Solution { + public boolean IsBalanced_Solution(TreeNode root) { + if (root == null) { + return true; + } + return Math.abs(treeDepth(root.left) - treeDepth(root.right)) <= 1 && IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right); + } + + public int treeDepth(TreeNode root) { + if (root == null) { + return 0; + } + return 1 + Math.max(treeDepth(root.left), treeDepth(root.right)); + } +} diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ81.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ81.java" new file mode 100644 index 0000000..f70b682 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ81.java" @@ -0,0 +1,30 @@ +// 81. 调整数组顺序使奇数位于偶数前面(二) + + +/* +双指针:左右指针从两边向中间遍历,交换奇偶数位置 + */ +public class Solution { + public int[] reOrderArrayTwo (int[] array) { + int n = array.length; + int left = 0, right = n - 1; + while (left < right) { + while (left < n && array[left] % 2 != 0) { + left++; + } + while (right >= 0 && array[right] % 2 == 0) { + right--; + } + if (left < right) { + swap(array, left, right); + } + } + return array; + } + + private void swap(int[] array, int x, int y) { + int temp = array[x]; + array[x] = array[y]; + array[y] = temp; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ82.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ82.java" new file mode 100644 index 0000000..61a3d82 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ82.java" @@ -0,0 +1,21 @@ +// 82. 二叉树中和为某一值的路径(一) + + +/* +递归: +1、终止条件:节点为空,说明没找到,返回false +2、函数作用:累减目标值,判断 目标值是否为0 且 是否为叶结点,若是说明找到符合条件的路径,返回true。否则继续往下判断左右子节点 +3、左右子节点需要同样的操作,调用同样的方法实现,只有找到一个符合条件即可,所以用或条件 + */ +public class Solution { + public boolean hasPathSum (TreeNode root, int sum) { + if (root == null) { + return false; + } + sum -= root.val; + if (sum == 0 && root.left == null && root.right == null) { + return true; + } + return hasPathSum(root.left, sum) || hasPathSum(root.right, sum); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ83.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ83.java" new file mode 100644 index 0000000..3b3ba1b --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ83.java" @@ -0,0 +1,84 @@ +// 83. 剪绳子(进阶版) + + +/* +在“14. 剪绳子”的基础上,对结果取余 + */ +public class Solution { + public long cutRope (long number) { + if (number == 2 || number == 3) { + return number - 1; + } + long mod = 998244353; + long res = 1; + while (number > 4) { + number -= 3; + res *= 3; + res %= mod; + } + return res * number % mod; + } +} + + +public class Solution { + public long cutRope (long number) { + if (number == 2 || number == 3) { + return number - 1; + } + long x = number % 3; + long y = number / 3; + if (x == 1) { + return (long) Math.pow(3, y - 1) * 4 % mod; + } else if (x == 2) { + return (long) Math.pow(3, y) * 2 % mod; + } else { + return (long) Math.pow(3, y) % mod; + } + } +} + + +/* +快速幂:以上解法都太慢了 +1、公式 + 1)b是偶数:a的b次方 = (a*a)的(b/2)次方 + 2)b是奇数:a的b次方 = (a*a)的(b/2)次方 * a +2、计算逻辑,每次循环幂减一半、基数翻倍,幂为奇数时结果乘基数 + + num res base +初始 5 1 3 +结果 5 3 9 + 2 9 81 + 1 81 6561 + */ +public class Solution { + long mod = 998244353; + + public long cutRope (long number) { + if (number == 2 || number == 3) { + return number - 1; + } + long x = number % 3; + long y = number / 3; + if (x == 1) { + return pow(3, y - 1) * 4 % mod; + } else if (x == 2) { + return pow(3, y) * 2 % mod; + } else { + return pow(3, y) % mod; + } + } + + private long pow(long base, long num) { + long res = 1; + while (num > 0) { + if (num % 2 == 1) { + res = res * base % mod; + } + base = base * base % mod; + num /= 2; + } + return res; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ84.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ84.java" new file mode 100644 index 0000000..cb1d317 --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ84.java" @@ -0,0 +1,32 @@ +// 84. 二叉树中和为某一值的路径(三) + + +/* +两层递归: +第一个递归 dfs 用于计算从某个结点开始往下产生的路径结点值和为sum的路径数 +第二个递归 FindPath 用于遍历每个节点开始的路径数 + */ +public class Solution { + private int res = 0; + + public int FindPath (TreeNode root, int sum) { + if (root != null) { + dfs(root, sum); + FindPath(root.left, sum); + FindPath(root.right, sum); + } + return res; + } + + private void dfs(TreeNode root, int target) { + if (root == null) { + return; + } + target -= root.val; + if (target == 0) { + res += 1; + } + dfs(root.left, target); + dfs(root.right, target); + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ85.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ85.java" new file mode 100644 index 0000000..ae4e80a --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ85.java" @@ -0,0 +1,36 @@ +// 85. 连续子数组的最大和(二) + + +/* +动态规划: +1、题目简化:求连续子数组最大和,并返回该子数组 +2、在“42. 连续子数组的最大和”的基础上,记录每个元素结尾的最大和连续子数组的左右边界, + 当 子数组和更大 或者 子数组和相等的情况下区间更长,则更新 最大和 与 最终的区间边界 +3、根据区间首尾获取子数组 + */ +public class Solution { + public int[] FindGreatestSumOfSubArray (int[] array) { + int n = array.length; + int[] dp = new int[n]; + dp[0] = array[0]; + int maxSum = dp[0]; + int left = 0, right = 0; + int maxLeft = 0, maxRight = 0; + for (int i = 1; i < n; i++) { + right++; + dp[i] = Math.max(dp[i - 1] + array[i], array[i]); + if (dp[i - 1] + array[i] < array[i]) { + left = right; + } + if (dp[i] > maxSum || (dp[i] == maxSum && right - left + 1 > maxRight - maxLeft + 1)) { + maxSum = dp[i]; + maxLeft = left; + maxRight = right; + } + } + int len = maxRight - maxLeft + 1; + int[] res = new int[len]; + System.arraycopy(array, maxLeft, res, 0, len); + return res; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ86.java" "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ86.java" new file mode 100644 index 0000000..c237f0f --- /dev/null +++ "b/\345\211\221\346\214\207Offer_Java_\346\226\260\347\211\210/JZ86.java" @@ -0,0 +1,29 @@ +// 86. 在二叉树中找到两个节点的最近公共祖先 + + +/* +思路同“236. 二叉树的最近公共祖先” +1、不利用二叉搜索树性质,直接当成普通二叉树进行节点遍历 +2、函数功能:在节点中找p、q,找不到返回-1,找到了返回该节点值 不继续往下找了 +3、递归逻辑: + 1)根节点找不到时,要再判断左右节点能否找到,因此调用递归函数得到左右节点寻找结果 + 2)拿结果做判断,如果左右都能找到,说明p、q在左右两边,当前根节点是最近公共祖先,返回根节点值 + 3)如果左边找到了,右边没找到,说明p、q都在左边,左边的节点值是最近公共祖先 + 如果右边找到了,左边没找到,说明p、q都在右边,右边的节点值是最近公共祖先 + */ +public class Solution { + public int lowestCommonAncestor (TreeNode root, int p, int q) { + if (root == null) { + return -1; + } + if (root.val == p || root.val == q) { + return root.val; + } + int left = lowestCommonAncestor(root.left, p, q); + int right = lowestCommonAncestor(root.right, p, q); + if (left != -1 && right != -1) { + return root.val; + } + return left != -1 ? left : right; + } +} \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/01.\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276.py" "b/\345\211\221\346\214\207Offer_Python/01.\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276.py" similarity index 95% rename from "\345\211\221\346\214\207Offer/01.\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276.py" rename to "\345\211\221\346\214\207Offer_Python/01.\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276.py" index 1df361d..8c6f12c 100644 --- "a/\345\211\221\346\214\207Offer/01.\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276.py" +++ "b/\345\211\221\346\214\207Offer_Python/01.\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276.py" @@ -1,42 +1,42 @@ -# 方法一:逐行遍历 -class Solution: - def Find(self, target, array): - for i in range(len(array)): - if target in array[i]: - return 'true' - return 'false' - -# 方法二:左下角开始遍历,大于向右,小于向上 -class Solution: - def Find(self, target, array): - i, j = len(array)-1, 0 - while i>=0 and jtemp: - j += 1 - elif target=0 and jtemp: + j += 1 + elif target>i & 1) for i in range(32)]) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/12.\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271.py" "b/\345\211\221\346\214\207Offer_Python/12.\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/12.\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271.py" rename to "\345\211\221\346\214\207Offer_Python/12.\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271.py" index 8c207b5..11749fd 100644 --- "a/\345\211\221\346\214\207Offer/12.\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/12.\346\225\260\345\200\274\347\232\204\346\225\264\346\225\260\346\254\241\346\226\271.py" @@ -1,18 +1,18 @@ -# 方法一:累乘 -class Solution: - def Power(self, base, exponent): - if base == 0: - return False - if exponent == 0: - return 1 - res = 1 - for i in range(abs(exponent)): - res *= base - if exponent < 0: - return 1/res - return res - -# 方法二:使用pow()函数 -class Solution: - def Power(self, base, exponent): +# 方法一:累乘 +class Solution: + def Power(self, base, exponent): + if base == 0: + return False + if exponent == 0: + return 1 + res = 1 + for i in range(abs(exponent)): + res *= base + if exponent < 0: + return 1/res + return res + +# 方法二:使用pow()函数 +class Solution: + def Power(self, base, exponent): return pow(base, exponent) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/13.\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242.py" "b/\345\211\221\346\214\207Offer_Python/13.\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/13.\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242.py" rename to "\345\211\221\346\214\207Offer_Python/13.\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242.py" index aba8091..c263766 100644 --- "a/\345\211\221\346\214\207Offer/13.\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242.py" +++ "b/\345\211\221\346\214\207Offer_Python/13.\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242.py" @@ -1,19 +1,19 @@ -# 方法一:使用一个数组 -class Solution: - def reOrderArray(self, array): - l = [] - for i in range(len(array)): - # 逆序访问,是奇数则插到数组第一位 - if array[-1-i]%2 != 0: - l.insert(0, array[-1-i]) - # 顺序访问,是偶数则追加到数组后面 - if array[i]%2 == 0: - l.append(array[i]) - return l - -# 方法二:使用两个数组,分别存放奇数和偶数 -class Solution: - def reOrderArray(self, array): - a = [x for x in array if x%2] - b = [x for x in array if not x%2] +# 方法一:使用一个数组 +class Solution: + def reOrderArray(self, array): + l = [] + for i in range(len(array)): + # 逆序访问,是奇数则插到数组第一位 + if array[-1-i]%2 != 0: + l.insert(0, array[-1-i]) + # 顺序访问,是偶数则追加到数组后面 + if array[i]%2 == 0: + l.append(array[i]) + return l + +# 方法二:使用两个数组,分别存放奇数和偶数 +class Solution: + def reOrderArray(self, array): + a = [x for x in array if x%2] + b = [x for x in array if not x%2] return a+b \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/14.\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254k\344\270\252\347\273\223\347\202\271.py" "b/\345\211\221\346\214\207Offer_Python/14.\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254k\344\270\252\347\273\223\347\202\271.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/14.\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254k\344\270\252\347\273\223\347\202\271.py" rename to "\345\211\221\346\214\207Offer_Python/14.\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254k\344\270\252\347\273\223\347\202\271.py" index a88eb18..e54619b 100644 --- "a/\345\211\221\346\214\207Offer/14.\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254k\344\270\252\347\273\223\347\202\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/14.\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254k\344\270\252\347\273\223\347\202\271.py" @@ -1,26 +1,26 @@ -# 方法一:数组存储链表结点值 -class Solution: - def FindKthToTail(self, head, k): - l = [] - while head: - l.append(head) - head = head.next - if k>len(l) or k<1: - return None - return l[-k] - -# 方法二:使用两个指针 -# 两个指针指向head,第一个指针先走k步。然后两个指针同时往后移,当第一个指针到达末尾时,第二个指针即在倒数第k个结点 -class Solution: - def FindKthToTail(self, head, k): - front, later = head, head - for i in range(k): - if not front: - return - if not front.next and i==k-1: - return head - front = front.next - while front.next: - front = front.next - later = later.next +# 方法一:数组存储链表结点值 +class Solution: + def FindKthToTail(self, head, k): + l = [] + while head: + l.append(head) + head = head.next + if k>len(l) or k<1: + return None + return l[-k] + +# 方法二:使用两个指针 +# 两个指针指向head,第一个指针先走k步。然后两个指针同时往后移,当第一个指针到达末尾时,第二个指针即在倒数第k个结点 +class Solution: + def FindKthToTail(self, head, k): + front, later = head, head + for i in range(k): + if not front: + return + if not front.next and i==k-1: + return head + front = front.next + while front.next: + front = front.next + later = later.next return later.next \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/15.\345\217\215\350\275\254\351\223\276\350\241\250.py" "b/\345\211\221\346\214\207Offer_Python/15.\345\217\215\350\275\254\351\223\276\350\241\250.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/15.\345\217\215\350\275\254\351\223\276\350\241\250.py" rename to "\345\211\221\346\214\207Offer_Python/15.\345\217\215\350\275\254\351\223\276\350\241\250.py" index 8686119..1b54c8b 100644 --- "a/\345\211\221\346\214\207Offer/15.\345\217\215\350\275\254\351\223\276\350\241\250.py" +++ "b/\345\211\221\346\214\207Offer_Python/15.\345\217\215\350\275\254\351\223\276\350\241\250.py" @@ -1,12 +1,12 @@ -# pre指向已反序的最后一个结点,pHead指向正在反序的结点,after指向下一个要反序的结点 -class Solution: - def ReverseList(self, pHead): - if not pHead or not pHead.next: - return pHead - pre, after = None, None - while pHead: - after = pHead.next - pHead.next = pre - pre = pHead - pHead = after +# pre指向已反序的最后一个结点,pHead指向正在反序的结点,after指向下一个要反序的结点 +class Solution: + def ReverseList(self, pHead): + if not pHead or not pHead.next: + return pHead + pre, after = None, None + while pHead: + after = pHead.next + pHead.next = pre + pre = pHead + pHead = after return pre \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/16.\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250.py" "b/\345\211\221\346\214\207Offer_Python/16.\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/16.\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250.py" rename to "\345\211\221\346\214\207Offer_Python/16.\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250.py" index 1c087f7..59006c0 100644 --- "a/\345\211\221\346\214\207Offer/16.\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250.py" +++ "b/\345\211\221\346\214\207Offer_Python/16.\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250.py" @@ -1,34 +1,34 @@ -# 递归 -class Solution: - # 方法作用:比较两个节点的值,合并较小者到链表 - def Merge(self, pHead1, pHead2): - head = None - # 终止条件是一个链表为空,处理方法是返回另一个链表 - if not pHead1: - return pHead2 - if not pHead2: - return pHead1 - else: - if pHead1.val <= pHead2.val: - head = pHead1 - # 提取重复逻辑 - head.next = self.Merge(pHead1.next, pHead2) - else: - head = pHead2 - head.next = self.Merge(pHead1, pHead2.next) - return head - - -class Solution: - def Merge(self, pHead1, pHead2): - p = q = ListNode(None) - while pHead1 and pHead2: - if pHead1.val < pHead2.val: - p.next = pHead1 - pHead1 = pHead1.next - else: - p.next = pHead2 - pHead2 = pHead2.next - p = p.next - p.next = pHead1 or pHead2 - return q.next +# 递归 +class Solution: + # 方法作用:比较两个节点的值,合并较小者到链表 + def Merge(self, pHead1, pHead2): + head = None + # 终止条件是一个链表为空,处理方法是返回另一个链表 + if not pHead1: + return pHead2 + if not pHead2: + return pHead1 + else: + if pHead1.val <= pHead2.val: + head = pHead1 + # 提取重复逻辑 + head.next = self.Merge(pHead1.next, pHead2) + else: + head = pHead2 + head.next = self.Merge(pHead1, pHead2.next) + return head + + +class Solution: + def Merge(self, pHead1, pHead2): + p = q = ListNode(None) + while pHead1 and pHead2: + if pHead1.val < pHead2.val: + p.next = pHead1 + pHead1 = pHead1.next + else: + p.next = pHead2 + pHead2 = pHead2.next + p = p.next + p.next = pHead1 or pHead2 + return q.next diff --git "a/\345\211\221\346\214\207Offer/17.\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204.py" "b/\345\211\221\346\214\207Offer_Python/17.\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/17.\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204.py" rename to "\345\211\221\346\214\207Offer_Python/17.\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204.py" index b675271..eb39739 100644 --- "a/\345\211\221\346\214\207Offer/17.\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204.py" +++ "b/\345\211\221\346\214\207Offer_Python/17.\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204.py" @@ -1,22 +1,22 @@ -# 递归:寻找相同结点需要递归,判断是否为子结构也需要递归 - -class Solution: - # 方法作用:A中寻找与B根结点相同的节点,并判断B是否为A的子结构 - def HasSubtree(self, pRoot1, pRoot2): - # 终止条件:A或B的根节点为空 - if not pRoot1 or not pRoot2: - # 处理方法 - return False - # 提取重复逻辑 - return self.is_subtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2) - - # 方法作用:判断两个结点是否相同 - def is_subtree(self, A, B): - # 终止条件:B先遍历完则返回ture - if not B: - return True - # 终止条件:A先遍历完或AB的值不相等,说明不是子结构 - if not A or A.val != B.val: - return False - # 提取重复逻辑。否则两值相等,再递归判断左右子树的值 +# 递归:寻找相同结点需要递归,判断是否为子结构也需要递归 + +class Solution: + # 方法作用:A中寻找与B根结点相同的节点,并判断B是否为A的子结构 + def HasSubtree(self, pRoot1, pRoot2): + # 终止条件:A或B的根节点为空 + if not pRoot1 or not pRoot2: + # 处理方法 + return False + # 提取重复逻辑 + return self.is_subtree(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2) + + # 方法作用:判断两个结点是否相同 + def is_subtree(self, A, B): + # 终止条件:B先遍历完则返回ture + if not B: + return True + # 终止条件:A先遍历完或AB的值不相等,说明不是子结构 + if not A or A.val != B.val: + return False + # 提取重复逻辑。否则两值相等,再递归判断左右子树的值 return self.is_subtree(A.left, B.left) and self.is_subtree(A.right, B.right) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/18.\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217.py" "b/\345\211\221\346\214\207Offer_Python/18.\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/18.\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217.py" rename to "\345\211\221\346\214\207Offer_Python/18.\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217.py" index bafd0b0..378ed74 100644 --- "a/\345\211\221\346\214\207Offer/18.\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217.py" +++ "b/\345\211\221\346\214\207Offer_Python/18.\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217.py" @@ -1,7 +1,7 @@ -class Solution: - # 方法作用:交换左右子树 - def Mirror(self, root): - if root: - root.left, root.right = root.right, root.left - self.Mirror(root.left) +class Solution: + # 方法作用:交换左右子树 + def Mirror(self, root): + if root: + root.left, root.right = root.right, root.left + self.Mirror(root.left) self.Mirror(root.right) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/19.\351\241\272\346\227\266\351\222\210\346\211\223\345\215\260\347\237\251\351\230\265.py" "b/\345\211\221\346\214\207Offer_Python/19.\351\241\272\346\227\266\351\222\210\346\211\223\345\215\260\347\237\251\351\230\265.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/19.\351\241\272\346\227\266\351\222\210\346\211\223\345\215\260\347\237\251\351\230\265.py" rename to "\345\211\221\346\214\207Offer_Python/19.\351\241\272\346\227\266\351\222\210\346\211\223\345\215\260\347\237\251\351\230\265.py" index 50944ca..8085c26 100644 --- "a/\345\211\221\346\214\207Offer/19.\351\241\272\346\227\266\351\222\210\346\211\223\345\215\260\347\237\251\351\230\265.py" +++ "b/\345\211\221\346\214\207Offer_Python/19.\351\241\272\346\227\266\351\222\210\346\211\223\345\215\260\347\237\251\351\230\265.py" @@ -1,47 +1,47 @@ -class Solution: - # matrix类型为二维列表,需要返回列表 - def printMatrix(self, matrix): - if not matrix: - return [] - rows = len(matrix) - cols = len(matrix[0]) - start = 0 # 代表循环次数,也可代表每一圈的起点 - result = [] - while rows > 2*start and cols > 2*start: # 循环次数为行列的最大值除以2取整 - endx = rows - 1 - start # 行数 - endy = cols - 1 - start # 列数 - for i in range(start, endy+1): # 第一行 - result.append(matrix[start][i]) - if start < endx: # 判断下面是否还有行 - for i in range(start+1,endx+1): # 最右列 - result.append(matrix[i][endy]) - if start < endx and start < endy: # 判断下面是否还有行,右面是否还有列 - for i in range(endy-1, start-1, -1): # 最下行 - result.append(matrix[endx][i]) - if start < endx-1 and start < endy: # 判断下面是否还有行,判断该列是否重复 - for i in range(endx-1, start, -1): # 最左列 - result.append(matrix[i][start]) - start += 1 - return result - - -class Solution: - def printMatrix(self, matrix): - if not matrix: - return [] - res = [] - while matrix: - # 弹出第一行 - res += matrix.pop(0) - # 添加最后一列。非空的行才能弹出元素,故需先判断是否为空 - if matrix and matrix[0]: - for row in matrix: - res.append(row.pop()) - # 弹出最后一行并反转 - if matrix: - res += matrix.pop()[::-1] - # 添加第一列 - if matrix and matrix[0]: - for row in matrix[::-1]: - res.append(row.pop(0)) - return res +class Solution: + # matrix类型为二维列表,需要返回列表 + def printMatrix(self, matrix): + if not matrix: + return [] + rows = len(matrix) + cols = len(matrix[0]) + start = 0 # 代表循环次数,也可代表每一圈的起点 + result = [] + while rows > 2*start and cols > 2*start: # 循环次数为行列的最大值除以2取整 + endx = rows - 1 - start # 行数 + endy = cols - 1 - start # 列数 + for i in range(start, endy+1): # 第一行 + result.append(matrix[start][i]) + if start < endx: # 判断下面是否还有行 + for i in range(start+1,endx+1): # 最右列 + result.append(matrix[i][endy]) + if start < endx and start < endy: # 判断下面是否还有行,右面是否还有列 + for i in range(endy-1, start-1, -1): # 最下行 + result.append(matrix[endx][i]) + if start < endx-1 and start < endy: # 判断下面是否还有行,判断该列是否重复 + for i in range(endx-1, start, -1): # 最左列 + result.append(matrix[i][start]) + start += 1 + return result + + +class Solution: + def printMatrix(self, matrix): + if not matrix: + return [] + res = [] + while matrix: + # 弹出第一行 + res += matrix.pop(0) + # 添加最后一列。非空的行才能弹出元素,故需先判断是否为空 + if matrix and matrix[0]: + for row in matrix: + res.append(row.pop()) + # 弹出最后一行并反转 + if matrix: + res += matrix.pop()[::-1] + # 添加第一列 + if matrix and matrix[0]: + for row in matrix[::-1]: + res.append(row.pop(0)) + return res diff --git "a/\345\211\221\346\214\207Offer/20.\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210.py" "b/\345\211\221\346\214\207Offer_Python/20.\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/20.\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210.py" rename to "\345\211\221\346\214\207Offer_Python/20.\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210.py" index e820083..213feb2 100644 --- "a/\345\211\221\346\214\207Offer/20.\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210.py" +++ "b/\345\211\221\346\214\207Offer_Python/20.\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210.py" @@ -1,30 +1,30 @@ -# 方法一:使用两个数组模拟栈 -class Solution: - def __init__(self): - self.stack = [] - self.min_stack = [] - def push(self, node): - self.stack.append(node) - if not self.min_stack or node <= self.min_stack[-1]: - self.min_stack.append(node) - def pop(self): - if self.stack[-1] == self.min_stack[-1]: - self.min_stack.pop() - self.stack.pop() - def top(self): - return self.stack[-1] - def min(self): - return self.min_stack[-1] - -# 方法二:使用一个数组模拟栈 -class Solution: - def __init__(self): - self.stack = [] - def push(self, node): - self.stack.append(node) - def pop(self): - self.stack.pop() - def top(self): - return self.stack[-1] - def min(self): +# 方法一:使用两个数组模拟栈 +class Solution: + def __init__(self): + self.stack = [] + self.min_stack = [] + def push(self, node): + self.stack.append(node) + if not self.min_stack or node <= self.min_stack[-1]: + self.min_stack.append(node) + def pop(self): + if self.stack[-1] == self.min_stack[-1]: + self.min_stack.pop() + self.stack.pop() + def top(self): + return self.stack[-1] + def min(self): + return self.min_stack[-1] + +# 方法二:使用一个数组模拟栈 +class Solution: + def __init__(self): + self.stack = [] + def push(self, node): + self.stack.append(node) + def pop(self): + self.stack.pop() + def top(self): + return self.stack[-1] + def min(self): return min(self.stack) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/21.\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.py" "b/\345\211\221\346\214\207Offer_Python/21.\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/21.\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.py" rename to "\345\211\221\346\214\207Offer_Python/21.\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.py" index 8ee2373..1fd54cf 100644 --- "a/\345\211\221\346\214\207Offer/21.\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/21.\346\240\210\347\232\204\345\216\213\345\205\245\343\200\201\345\274\271\345\207\272\345\272\217\345\210\227.py" @@ -1,13 +1,13 @@ -# 数据入栈,当数据与弹出序列头元素相等时,则数据出栈且序列头元素弹出,重复以上步骤,最终若栈为空则该序列是符合的弹出序列 -def IsPopOrder(self, pushV, popV): - if not pushV: - return False - stack = [] - for i in pushV: - stack.append(i) - while len(stack) and stack[-1] == popV[0]: - stack.pop() - popV.pop(0) - if len(stack): - return False +# 数据入栈,当数据与弹出序列头元素相等时,则数据出栈且序列头元素弹出,重复以上步骤,最终若栈为空则该序列是符合的弹出序列 +def IsPopOrder(self, pushV, popV): + if not pushV: + return False + stack = [] + for i in pushV: + stack.append(i) + while len(stack) and stack[-1] == popV[0]: + stack.pop() + popV.pop(0) + if len(stack): + return False return True \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/22.\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" "b/\345\211\221\346\214\207Offer_Python/22.\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/22.\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" rename to "\345\211\221\346\214\207Offer_Python/22.\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" index 9263bdf..271fc86 100644 --- "a/\345\211\221\346\214\207Offer/22.\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" +++ "b/\345\211\221\346\214\207Offer_Python/22.\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" @@ -1,16 +1,16 @@ -# res存放每一层结点的值,cur存放当前层和下一层结点 -class Solution: - def PrintFromTopToBottom(self, root): - if not root: - return [] - res = [] - cur = [root] - while cur: - for i in cur: - t = cur.pop(0) - res.append(t.val) - if t.left: - cur.append(t.left) - if t.right: - cur.append(t.right) +# res存放每一层结点的值,cur存放当前层和下一层结点 +class Solution: + def PrintFromTopToBottom(self, root): + if not root: + return [] + res = [] + cur = [root] + while cur: + for i in cur: + t = cur.pop(0) + res.append(t.val) + if t.left: + cur.append(t.left) + if t.right: + cur.append(t.right) return res \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/23.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227.py" "b/\345\211\221\346\214\207Offer_Python/23.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/23.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227.py" rename to "\345\211\221\346\214\207Offer_Python/23.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227.py" index a02ab9d..46795fa 100644 --- "a/\345\211\221\346\214\207Offer/23.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/23.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227.py" @@ -1,24 +1,24 @@ -# 已知条件: -# 1、后序序列最后一个值为root -# 2、二叉搜索树左子树值都比root小,右子树值都比root大。 -# -# 步骤: -# 1、确定root; -# 2、遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树; -# 3、遍历右子树,若发现有小于root的值,则直接返回false; -# 4、分别判断左子树和右子树是否仍是二叉搜索树(即递归步骤1、2、3)。 -class Solution: - def VerifySquenceOfBST(self, sequence): - length = len(sequence) - if length == 0: - return False - if length == 1: - return True - root = sequence[-1] - left = 0 - while sequence[left] < root: - left += 1 - for i in range(left, length-1): - if sequence[i] < root: - return False +# 已知条件: +# 1、后序序列最后一个值为root +# 2、二叉搜索树左子树值都比root小,右子树值都比root大。 +# +# 步骤: +# 1、确定root; +# 2、遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树; +# 3、遍历右子树,若发现有小于root的值,则直接返回false; +# 4、分别判断左子树和右子树是否仍是二叉搜索树(即递归步骤1、2、3)。 +class Solution: + def VerifySquenceOfBST(self, sequence): + length = len(sequence) + if length == 0: + return False + if length == 1: + return True + root = sequence[-1] + left = 0 + while sequence[left] < root: + left += 1 + for i in range(left, length-1): + if sequence[i] < root: + return False return self.VerifySquenceOfBST(sequence[:left]) or self.VerifySquenceOfBST(sequence[left:length-1]) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/24.\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204.py" "b/\345\211\221\346\214\207Offer_Python/24.\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/24.\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204.py" rename to "\345\211\221\346\214\207Offer_Python/24.\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204.py" index 0490f59..64b8ccd 100644 --- "a/\345\211\221\346\214\207Offer/24.\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204.py" +++ "b/\345\211\221\346\214\207Offer_Python/24.\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204.py" @@ -1,16 +1,16 @@ -class Solution: - # 方法作用极简化:判断一个结点的值与给定值是否相同,相同则返回该值 - def FindPath(self, root, expectNumber): - # 无的情况 - if not root: - return [] - # 1个结点的情况 - if not root.left and not root.right and root.val==expectNumber: - return [[root.val]] - # 2或3个结点的情况,由此类推到多的情况 - left = self.FindPath(root.left, expectNumber-root.val) - right = self.FindPath(root.right, expectNumber-root.val) - res = [] - for i in left+right: - res.append([root.val] + i) +class Solution: + # 方法作用极简化:判断一个结点的值与给定值是否相同,相同则返回该值 + def FindPath(self, root, expectNumber): + # 无的情况 + if not root: + return [] + # 1个结点的情况 + if not root.left and not root.right and root.val==expectNumber: + return [[root.val]] + # 2或3个结点的情况,由此类推到多的情况 + left = self.FindPath(root.left, expectNumber-root.val) + right = self.FindPath(root.right, expectNumber-root.val) + res = [] + for i in left+right: + res.append([root.val] + i) return res \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/25.\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.py" "b/\345\211\221\346\214\207Offer_Python/25.\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/25.\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.py" rename to "\345\211\221\346\214\207Offer_Python/25.\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.py" index 08a688b..113e99c 100644 --- "a/\345\211\221\346\214\207Offer/25.\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.py" +++ "b/\345\211\221\346\214\207Offer_Python/25.\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.py" @@ -1,17 +1,17 @@ -class RandomListNode: - def __init__(self, x): - self.label = x - self.next = None - self.random = None -class Solution: - # 返回 RandomListNode - def Clone(self, pHead): - if not pHead: - return - # 新建随机结点 - newNode = RandomListNode(pHead.label) - # 随机结点指向 - newNode.random = pHead.random - # 下一结点指向。由于旧链表下一结点需要同样的操作,使用递归 - newNode.next = self.Clone(pHead.next) +class RandomListNode: + def __init__(self, x): + self.label = x + self.next = None + self.random = None +class Solution: + # 返回 RandomListNode + def Clone(self, pHead): + if not pHead: + return + # 新建随机结点 + newNode = RandomListNode(pHead.label) + # 随机结点指向 + newNode.random = pHead.random + # 下一结点指向。由于旧链表下一结点需要同样的操作,使用递归 + newNode.next = self.Clone(pHead.next) return newNode \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/26.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250.py" "b/\345\211\221\346\214\207Offer_Python/26.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/26.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250.py" rename to "\345\211\221\346\214\207Offer_Python/26.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250.py" index ff27167..8474879 100644 --- "a/\345\211\221\346\214\207Offer/26.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250.py" +++ "b/\345\211\221\346\214\207Offer_Python/26.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250.py" @@ -1,50 +1,50 @@ -# 方法一:根节点与叶结点连接 -class Solution: - def Convert(self, pRootOfTree): - root = pRootOfTree - if not root: - return None - if not root.left and not root.right: - return root - # 处理左子树 - left = self.Convert(root.left) - # 连接根与左子树最深的右叶结点,即左子树最大的结点 - if left: - while(left.right): - left=left.right - root.left = left - left.right = root - # 处理右子树 - right = self.Convert(root.right) - # 连接根与右子树最深的左叶结点,即右子树最小的结点 - if right: - while(right.left): - right=right.left - root.right = right - right.left = root - while(root.left): - root = root.left - return root - -# 方法二:中序遍历得到排序的数组,相邻两个结点相互连接 -class Solution: - def __init__(self): - self.array = [] - - def Convert(self, pRootOfTree): - if not pRootOfTree: - return None - self.mid_order(pRootOfTree) - for i in range(len(self.array)-1): - pre = self.array[i] - after = self.array[i+1] - pre.right = after - after.left = pre - return self.array[0] - - def mid_order(self, root): - if not root: - return None - self.mid_order(root.left) - self.array.append(root) +# 方法一:根节点与叶结点连接 +class Solution: + def Convert(self, pRootOfTree): + root = pRootOfTree + if not root: + return None + if not root.left and not root.right: + return root + # 处理左子树 + left = self.Convert(root.left) + # 连接根与左子树最深的右叶结点,即左子树最大的结点 + if left: + while(left.right): + left=left.right + root.left = left + left.right = root + # 处理右子树 + right = self.Convert(root.right) + # 连接根与右子树最深的左叶结点,即右子树最小的结点 + if right: + while(right.left): + right=right.left + root.right = right + right.left = root + while(root.left): + root = root.left + return root + +# 方法二:中序遍历得到排序的数组,相邻两个结点相互连接 +class Solution: + def __init__(self): + self.array = [] + + def Convert(self, pRootOfTree): + if not pRootOfTree: + return None + self.mid_order(pRootOfTree) + for i in range(len(self.array)-1): + pre = self.array[i] + after = self.array[i+1] + pre.right = after + after.left = pre + return self.array[0] + + def mid_order(self, root): + if not root: + return None + self.mid_order(root.left) + self.array.append(root) self.mid_order(root.right) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/27.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.py" "b/\345\211\221\346\214\207Offer_Python/27.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/27.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.py" rename to "\345\211\221\346\214\207Offer_Python/27.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.py" index ca20aaf..e8ff136 100644 --- "a/\345\211\221\346\214\207Offer/27.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/27.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.py" @@ -1,7 +1,7 @@ -# 使用迭代工具类的排列方法 -import itertools -class Solution: - def Permutation(self, ss): - if not ss: - return [] +# 使用迭代工具类的排列方法 +import itertools +class Solution: + def Permutation(self, ss): + if not ss: + return [] return sorted(list(set(map(''.join, itertools.permutations(ss))))) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/28.\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227.py" "b/\345\211\221\346\214\207Offer_Python/28.\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/28.\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227.py" rename to "\345\211\221\346\214\207Offer_Python/28.\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227.py" index 07f239a..5adc2ce 100644 --- "a/\345\211\221\346\214\207Offer/28.\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/28.\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227.py" @@ -1,24 +1,24 @@ -# 方法一:使用列表的count()方法统计次数 -class Solution: - def MoreThanHalfNum_Solution(self, numbers): - items = list(set(numbers)) - for i in items: - if numbers.count(i) > len(numbers)/2: - return i - return 0 - -# 方法二:使用字典统计次数 -class Solution: - def MoreThanHalfNum_Solution(self, numbers): - if not numbers: - return 0 - d = dict() - for i in numbers: - if i in d: - d[i] += 1 - else: - d[i] = 1 - for k in d: - if d[k] > len(numbers)/2: - return k +# 方法一:使用列表的count()方法统计次数 +class Solution: + def MoreThanHalfNum_Solution(self, numbers): + items = list(set(numbers)) + for i in items: + if numbers.count(i) > len(numbers)/2: + return i + return 0 + +# 方法二:使用字典统计次数 +class Solution: + def MoreThanHalfNum_Solution(self, numbers): + if not numbers: + return 0 + d = dict() + for i in numbers: + if i in d: + d[i] += 1 + else: + d[i] = 1 + for k in d: + if d[k] > len(numbers)/2: + return k return 0 \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/29.\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260.py" "b/\345\211\221\346\214\207Offer_Python/29.\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/29.\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260.py" rename to "\345\211\221\346\214\207Offer_Python/29.\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260.py" index c462686..9086631 100644 --- "a/\345\211\221\346\214\207Offer/29.\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260.py" +++ "b/\345\211\221\346\214\207Offer_Python/29.\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260.py" @@ -1,15 +1,15 @@ -# 方法一:使用sorted()函数 -class Solution: - def GetLeastNumbers_Solution(self, tinput, k): - if k > len(tinput): - return [] - t = sorted(tinput) - return t[:k] - -# 方法二:使用sort()方法 -class Solution: - def GetLeastNumbers_Solution(self, tinput, k): - if k > len(tinput): - return [] - tinput.sort() +# 方法一:使用sorted()函数 +class Solution: + def GetLeastNumbers_Solution(self, tinput, k): + if k > len(tinput): + return [] + t = sorted(tinput) + return t[:k] + +# 方法二:使用sort()方法 +class Solution: + def GetLeastNumbers_Solution(self, tinput, k): + if k > len(tinput): + return [] + tinput.sort() return tinput[:k] \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/30.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214.py" "b/\345\211\221\346\214\207Offer_Python/30.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/30.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214.py" rename to "\345\211\221\346\214\207Offer_Python/30.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214.py" index ab63f6f..dbc5ea2 100644 --- "a/\345\211\221\346\214\207Offer/30.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214.py" +++ "b/\345\211\221\346\214\207Offer_Python/30.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214.py" @@ -1,28 +1,28 @@ -# 方法一:遍历数组每个值作为起点,每次不断加后面的值,使用数组存放每次求和的结果,最终排序取最大值 -class Solution: - def FindGreatestSumOfSubArray(self, array): - l = [] - for i in range(len(array)): - maxSum = array[i] - l.append(maxSum) - for j in range(i+1, len(array)): - maxSum += array[j] - l.append(maxSum) - l.sort() - return l[-1] - -# 方法二:往后累加,得到更大的值则保存,若累加结果小于0则重新设置起点 -class Solution: - def FindGreatestSumOfSubArray(self, array): - maxSum, curSum = 0, 0 - maxN = max(array) - if maxN < 0: - return maxN - for i in range(len(array)): - curSum += array[i] - if curSum > maxSum: - maxSum = curSum - # 小于0则前面部分负大于正,重新设置子序列起点 - if curSum < 0: - curSum = 0 +# 方法一:遍历数组每个值作为起点,每次不断加后面的值,使用数组存放每次求和的结果,最终排序取最大值 +class Solution: + def FindGreatestSumOfSubArray(self, array): + l = [] + for i in range(len(array)): + maxSum = array[i] + l.append(maxSum) + for j in range(i+1, len(array)): + maxSum += array[j] + l.append(maxSum) + l.sort() + return l[-1] + +# 方法二:往后累加,得到更大的值则保存,若累加结果小于0则重新设置起点 +class Solution: + def FindGreatestSumOfSubArray(self, array): + maxSum, curSum = 0, 0 + maxN = max(array) + if maxN < 0: + return maxN + for i in range(len(array)): + curSum += array[i] + if curSum > maxSum: + maxSum = curSum + # 小于0则前面部分负大于正,重新设置子序列起点 + if curSum < 0: + curSum = 0 return maxSum \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/31.\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" "b/\345\211\221\346\214\207Offer_Python/31.\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/31.\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" rename to "\345\211\221\346\214\207Offer_Python/31.\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" index d663b71..f2658a5 100644 --- "a/\345\211\221\346\214\207Offer/31.\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" +++ "b/\345\211\221\346\214\207Offer_Python/31.\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" @@ -1,28 +1,28 @@ -# 方法一:判断整数每个数字 -class Solution: - def NumberOf1Between1AndN_Solution(self, n): - count = 0 - for i in range(1, n+1): - temp = i - while(temp): - if temp%10 == 1: - count += 1 - temp /= 10 - return count - -# 方法二:将整数转为字符串逐位判断 -class Solution: - def NumberOf1Between1AndN_Solution(self, n): - count = 0 - for i in range(1, n+1): - s = str(i) - for j in s: - if j == '1': - count += 1 - return count - -# 方法三:将整数转为字符串,组合含有‘1’的字符串,再统计‘1’的个数 -def NumberOf1Between1AndN_Solution(self, n): - a = map(str, range(n+1)) - ones = [i for i in a if '1' in i] +# 方法一:判断整数每个数字 +class Solution: + def NumberOf1Between1AndN_Solution(self, n): + count = 0 + for i in range(1, n+1): + temp = i + while(temp): + if temp%10 == 1: + count += 1 + temp /= 10 + return count + +# 方法二:将整数转为字符串逐位判断 +class Solution: + def NumberOf1Between1AndN_Solution(self, n): + count = 0 + for i in range(1, n+1): + s = str(i) + for j in s: + if j == '1': + count += 1 + return count + +# 方法三:将整数转为字符串,组合含有‘1’的字符串,再统计‘1’的个数 +def NumberOf1Between1AndN_Solution(self, n): + a = map(str, range(n+1)) + ones = [i for i in a if '1' in i] return ''.join(ones).count('1') \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/32.\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260.py" "b/\345\211\221\346\214\207Offer_Python/32.\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/32.\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260.py" rename to "\345\211\221\346\214\207Offer_Python/32.\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260.py" index e3526bc..0541a62 100644 --- "a/\345\211\221\346\214\207Offer/32.\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260.py" +++ "b/\345\211\221\346\214\207Offer_Python/32.\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260.py" @@ -1,16 +1,16 @@ -# 方法一:字符串比较并排序 -class Solution: - def PrintMinNumber(self, numbers): - num = map(str, numbers) - num.sort(lambda x, y: cmp(x+y, y+x)) - return ''.join(num) - -# 方法二:排列组合后求最小值 -import itertools -class Solution: - def PrintMinNumber(self, numbers): - if not numbers: - return '' - num = map(str, numbers) - l = itertools.permutations(num) +# 方法一:字符串比较并排序 +class Solution: + def PrintMinNumber(self, numbers): + num = map(str, numbers) + num.sort(lambda x, y: cmp(x+y, y+x)) + return ''.join(num) + +# 方法二:排列组合后求最小值 +import itertools +class Solution: + def PrintMinNumber(self, numbers): + if not numbers: + return '' + num = map(str, numbers) + l = itertools.permutations(num) return min(map(int,[''.join(i) for i in l])) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/33.\344\270\221\346\225\260.py" "b/\345\211\221\346\214\207Offer_Python/33.\344\270\221\346\225\260.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/33.\344\270\221\346\225\260.py" rename to "\345\211\221\346\214\207Offer_Python/33.\344\270\221\346\225\260.py" index 3bb46ff..ac70413 100644 --- "a/\345\211\221\346\214\207Offer/33.\344\270\221\346\225\260.py" +++ "b/\345\211\221\346\214\207Offer_Python/33.\344\270\221\346\225\260.py" @@ -1,18 +1,18 @@ -# 一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到。 -# 三个队列是有序的,所以取出三个头中最小的,即是新的丑数 -class Solution: - def GetUglyNumber_Solution(self, index): - if index == 0: - return 0 - res = [1] - t2, t3, t5 = 0, 0, 0 - for i in range(index-1): - new = min(res[t2]*2, res[t3]*3, res[t5]*5) - res.append(new) - if new%2 == 0: - t2 += 1 - if new%3 == 0: - t3 += 1 - if new%5 == 0: - t5 += 1 +# 一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到。 +# 三个队列是有序的,所以取出三个头中最小的,即是新的丑数 +class Solution: + def GetUglyNumber_Solution(self, index): + if index == 0: + return 0 + res = [1] + t2, t3, t5 = 0, 0, 0 + for i in range(index-1): + new = min(res[t2]*2, res[t3]*3, res[t5]*5) + res.append(new) + if new%2 == 0: + t2 += 1 + if new%3 == 0: + t3 += 1 + if new%5 == 0: + t5 += 1 return res[-1] \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/34.\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246.py" "b/\345\211\221\346\214\207Offer_Python/34.\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/34.\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246.py" rename to "\345\211\221\346\214\207Offer_Python/34.\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246.py" index 3ccf5ab..a59a915 100644 --- "a/\345\211\221\346\214\207Offer/34.\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246.py" +++ "b/\345\211\221\346\214\207Offer_Python/34.\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246.py" @@ -1,7 +1,7 @@ -class Solution: - def FirstNotRepeatingChar(self, s): - if not s: - return -1 - for index, value in enumerate(s): - if s.count(value) == 1: +class Solution: + def FirstNotRepeatingChar(self, s): + if not s: + return -1 + for index, value in enumerate(s): + if s.count(value) == 1: return index \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/35.\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.py" "b/\345\211\221\346\214\207Offer_Python/35.\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/35.\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.py" rename to "\345\211\221\346\214\207Offer_Python/35.\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.py" index b1d6a4f..ab723ad 100644 --- "a/\345\211\221\346\214\207Offer/35.\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/35.\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.py" @@ -1,58 +1,58 @@ -# 方法一:归并排序 -class Solution: - def InversePairs(self, data): - return self.inverseCount(data[:], 0, len(data)-1, data[:])%1000000007 - - def inverseCount(self, tmp, start, end, data): - if end-start <1: - return 0 - if end - start == 1: - if data[start]<=data[end]: - return 0 - else: - tmp[start], tmp[end] = data[end], data[start] - return 1 - mid = (start+end)//2 - count = self.inverseCount(data, start, mid, tmp) + self.inverseCount(data, mid+1, end, tmp) - i = start - j = mid + 1 - ind = start - while(i <= mid and j <= end): - if data[i] <= data[j]: - tmp[ind] = data[i] - i += 1 - else: - tmp[ind] = data[j] - count += mid - i + 1 - j += 1 - ind += 1 - while(i<=mid): - tmp[ind] = data[i] - i += 1 - ind += 1 - while(j<=end): - tmp[ind] = data[j] - j += 1 - ind += 1 - return count - -# 方法二:暴力破解。算法复杂度偏大 -class Solution: - def InversePairs(self, data): - count = 0 - for i in range(len(data)-1): - for j in range(i+1, len(data)): - if data[i] > data[j]: - count += 1 - return count%1000000007 - -# 方法三:最小元素前有几个数字就有几个逆序对,移除最小元素后,在剩余数组中再重复以上步骤。算法复杂度偏大。 -class Solution: - def InversePairs(self, data): - count = 0 - copy = [i for i in data] - copy.sort() - for i in range(len(copy)): - count += data.index(copy[i]) - data.remove(copy[i]) +# 方法一:归并排序 +class Solution: + def InversePairs(self, data): + return self.inverseCount(data[:], 0, len(data)-1, data[:])%1000000007 + + def inverseCount(self, tmp, start, end, data): + if end-start <1: + return 0 + if end - start == 1: + if data[start]<=data[end]: + return 0 + else: + tmp[start], tmp[end] = data[end], data[start] + return 1 + mid = (start+end)//2 + count = self.inverseCount(data, start, mid, tmp) + self.inverseCount(data, mid+1, end, tmp) + i = start + j = mid + 1 + ind = start + while(i <= mid and j <= end): + if data[i] <= data[j]: + tmp[ind] = data[i] + i += 1 + else: + tmp[ind] = data[j] + count += mid - i + 1 + j += 1 + ind += 1 + while(i<=mid): + tmp[ind] = data[i] + i += 1 + ind += 1 + while(j<=end): + tmp[ind] = data[j] + j += 1 + ind += 1 + return count + +# 方法二:暴力破解。算法复杂度偏大 +class Solution: + def InversePairs(self, data): + count = 0 + for i in range(len(data)-1): + for j in range(i+1, len(data)): + if data[i] > data[j]: + count += 1 + return count%1000000007 + +# 方法三:最小元素前有几个数字就有几个逆序对,移除最小元素后,在剩余数组中再重复以上步骤。算法复杂度偏大。 +class Solution: + def InversePairs(self, data): + count = 0 + copy = [i for i in data] + copy.sort() + for i in range(len(copy)): + count += data.index(copy[i]) + data.remove(copy[i]) return count%1000000007 \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/36.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271.py" "b/\345\211\221\346\214\207Offer_Python/36.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/36.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271.py" rename to "\345\211\221\346\214\207Offer_Python/36.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271.py" index 84ad006..03e88db 100644 --- "a/\345\211\221\346\214\207Offer/36.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/36.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271.py" @@ -1,26 +1,26 @@ -# 方法一:用数组存放一个链表结点值,遍历另一个链表判断是否有结点值在该数组中 -class Solution: - def FindFirstCommonNode(self, pHead1, pHead2): - l = [] - while pHead1: - l.append(pHead1) - pHead1 = pHead1.next - while pHead2: - if pHead2 in l: - return pHead2 - pHead2 = pHead2.next - -# 方法二:用两个指针扫描连个链表,最终两个指针到达 null 或者到达公共结点 -class Solution: - def FindFirstCommonNode(self, pHead1, pHead2): - p1 = pHead1 - p2 = pHead2 - while p1 != p2: - p1 = p1.next if p1 != None else pHead2 - p2 = p2.next if p2 != None else pHead1 - return p1 - - # while p1 != p2: - # p1 = p1.next if p1 else pHead2 - # p2 = p2.next if p2 else pHead1 +# 方法一:用数组存放一个链表结点值,遍历另一个链表判断是否有结点值在该数组中 +class Solution: + def FindFirstCommonNode(self, pHead1, pHead2): + l = [] + while pHead1: + l.append(pHead1) + pHead1 = pHead1.next + while pHead2: + if pHead2 in l: + return pHead2 + pHead2 = pHead2.next + +# 方法二:用两个指针扫描连个链表,最终两个指针到达 null 或者到达公共结点 +class Solution: + def FindFirstCommonNode(self, pHead1, pHead2): + p1 = pHead1 + p2 = pHead2 + while p1 != p2: + p1 = p1.next if p1 != None else pHead2 + p2 = p2.next if p2 != None else pHead1 + return p1 + + # while p1 != p2: + # p1 = p1.next if p1 else pHead2 + # p2 = p2.next if p2 else pHead1 # return p1 \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/37.\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" "b/\345\211\221\346\214\207Offer_Python/37.\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/37.\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" rename to "\345\211\221\346\214\207Offer_Python/37.\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" index 358b852..45c7266 100644 --- "a/\345\211\221\346\214\207Offer/37.\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" +++ "b/\345\211\221\346\214\207Offer_Python/37.\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.py" @@ -1,4 +1,4 @@ -# 直接使用count()方法 -class Solution: - def GetNumberOfK(self, data, k): +# 直接使用count()方法 +class Solution: + def GetNumberOfK(self, data, k): return data.count(k) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/38.\344\272\214\345\217\211\346\240\221\347\232\204\346\267\261\345\272\246.py" "b/\345\211\221\346\214\207Offer_Python/38.\344\272\214\345\217\211\346\240\221\347\232\204\346\267\261\345\272\246.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/38.\344\272\214\345\217\211\346\240\221\347\232\204\346\267\261\345\272\246.py" rename to "\345\211\221\346\214\207Offer_Python/38.\344\272\214\345\217\211\346\240\221\347\232\204\346\267\261\345\272\246.py" index e5209c8..e5773f7 100644 --- "a/\345\211\221\346\214\207Offer/38.\344\272\214\345\217\211\346\240\221\347\232\204\346\267\261\345\272\246.py" +++ "b/\345\211\221\346\214\207Offer_Python/38.\344\272\214\345\217\211\346\240\221\347\232\204\346\267\261\345\272\246.py" @@ -1,7 +1,7 @@ -class Solution: - def TreeDepth(self, pRoot): - # 无结点的情况 - if not pRoot: - return 0 - # 1到多个结点的情况 +class Solution: + def TreeDepth(self, pRoot): + # 无结点的情况 + if not pRoot: + return 0 + # 1到多个结点的情况 return 1 + max(self.TreeDepth(pRoot.left), self.TreeDepth(pRoot.right)) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/39.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" "b/\345\211\221\346\214\207Offer_Python/39.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/39.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" rename to "\345\211\221\346\214\207Offer_Python/39.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" index a27a196..0a46cdf 100644 --- "a/\345\211\221\346\214\207Offer/39.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" +++ "b/\345\211\221\346\214\207Offer_Python/39.\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.py" @@ -1,15 +1,15 @@ -# 平衡二叉树:二叉树的每个节点的左子树和右子树的深度差不大于1 -class Solution: - # 判断结点的左右子树深度差是否大于1 - def IsBalanced_Solution(self, pRoot): - if not pRoot: - return True - if abs(self.TreeDepth(pRoot.left) - self.TreeDepth(pRoot.right)) > 1: - return False - return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right) - - # 求结点的左右子树的最大深度 - def TreeDepth(self, pRoot): - if not pRoot: - return 0 +# 平衡二叉树:二叉树的每个节点的左子树和右子树的深度差不大于1 +class Solution: + # 判断结点的左右子树深度差是否大于1 + def IsBalanced_Solution(self, pRoot): + if not pRoot: + return True + if abs(self.TreeDepth(pRoot.left) - self.TreeDepth(pRoot.right)) > 1: + return False + return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right) + + # 求结点的左右子树的最大深度 + def TreeDepth(self, pRoot): + if not pRoot: + return 0 return max(self.TreeDepth(pRoot.left), self.TreeDepth(pRoot.right)) + 1 \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/40.\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" "b/\345\211\221\346\214\207Offer_Python/40.\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/40.\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" rename to "\345\211\221\346\214\207Offer_Python/40.\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" index c4d0fd5..7d80881 100644 --- "a/\345\211\221\346\214\207Offer/40.\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/40.\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227.py" @@ -1,31 +1,31 @@ -# 方法一:使用数组添加删除数字,出现偶数次的数字最终会被删除 -class Solution: - def FindNumsAppearOnce(self, array): - a = [] - for i in array: - if i not in a: - a.append(i) - else: - a.remove(i) - return a - -# 方法二:使用count()方法统计出现1次的数字 -class Solution: - def FindNumsAppearOnce(self, array): - a = [] - for i in array: - if array.count(i)==1: - a.append(i) - return a - -# 方法二:使用字典统计数字出现的次数,返回出现1次的数字 -class Solution: - def FindNumsAppearOnce(self, array): - d = {} - for i in array: - if i in d: - d[i] += 1 - else: - d[i] = 1 - res = [i for i in d if d[i]==1] +# 方法一:使用数组添加删除数字,出现偶数次的数字最终会被删除 +class Solution: + def FindNumsAppearOnce(self, array): + a = [] + for i in array: + if i not in a: + a.append(i) + else: + a.remove(i) + return a + +# 方法二:使用count()方法统计出现1次的数字 +class Solution: + def FindNumsAppearOnce(self, array): + a = [] + for i in array: + if array.count(i)==1: + a.append(i) + return a + +# 方法二:使用字典统计数字出现的次数,返回出现1次的数字 +class Solution: + def FindNumsAppearOnce(self, array): + d = {} + for i in array: + if i in d: + d[i] += 1 + else: + d[i] = 1 + res = [i for i in d if d[i]==1] return res \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/41.\345\222\214\344\270\272S\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227.py" "b/\345\211\221\346\214\207Offer_Python/41.\345\222\214\344\270\272S\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/41.\345\222\214\344\270\272S\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227.py" rename to "\345\211\221\346\214\207Offer_Python/41.\345\222\214\344\270\272S\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227.py" index 9876341..b7422d5 100644 --- "a/\345\211\221\346\214\207Offer/41.\345\222\214\344\270\272S\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/41.\345\222\214\344\270\272S\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227.py" @@ -1,38 +1,38 @@ -# 方法一:i遍历起点,j遍历起点后的序列 -class Solution: - def FindContinuousSequence(self, tsum): - if tsum < 3: - return [] - l = [] - end = (tsum+1)/2 - for i in range(1, end): - nsum = i - for j in range(i+1, end+1): - nsum += j - if nsum == tsum: - l.append(range(i, j+1)) - if nsum > tsum: - break - return l - -# 方法二:窗口滑动 -class Solution: - def FindContinuousSequence(self, tsum): - if tsum < 3: - return [] - res = [] - start = 1 - end = 2 - s = start + end - while start < (tsum+1)/2: - if s < tsum: - end += 1 - s += end - elif s == tsum: - res.append(range(start, end+1)) - s -= start - start += 1 - else: - s -= start - start += 1 +# 方法一:i遍历起点,j遍历起点后的序列 +class Solution: + def FindContinuousSequence(self, tsum): + if tsum < 3: + return [] + l = [] + end = (tsum+1)/2 + for i in range(1, end): + nsum = i + for j in range(i+1, end+1): + nsum += j + if nsum == tsum: + l.append(range(i, j+1)) + if nsum > tsum: + break + return l + +# 方法二:窗口滑动 +class Solution: + def FindContinuousSequence(self, tsum): + if tsum < 3: + return [] + res = [] + start = 1 + end = 2 + s = start + end + while start < (tsum+1)/2: + if s < tsum: + end += 1 + s += end + elif s == tsum: + res.append(range(start, end+1)) + s -= start + start += 1 + else: + s -= start + start += 1 return res \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/42.\345\222\214\344\270\272S\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227.py" "b/\345\211\221\346\214\207Offer_Python/42.\345\222\214\344\270\272S\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/42.\345\222\214\344\270\272S\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227.py" rename to "\345\211\221\346\214\207Offer_Python/42.\345\222\214\344\270\272S\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227.py" index a62e9a7..4b2dbb1 100644 --- "a/\345\211\221\346\214\207Offer/42.\345\222\214\344\270\272S\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/42.\345\222\214\344\270\272S\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227.py" @@ -1,7 +1,7 @@ -# 递增排序的数组,所以第一对的乘积就是最小的 -class Solution: - def FindNumbersWithSum(self, array, tsum): - for i in array: - if tsum-i in array: - return [i, tsum-i] +# 递增排序的数组,所以第一对的乘积就是最小的 +class Solution: + def FindNumbersWithSum(self, array, tsum): + for i in array: + if tsum-i in array: + return [i, tsum-i] return [] \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/43.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" "b/\345\211\221\346\214\207Offer_Python/43.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/43.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" rename to "\345\211\221\346\214\207Offer_Python/43.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" index af9309f..cc1d13f 100644 --- "a/\345\211\221\346\214\207Offer/43.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" +++ "b/\345\211\221\346\214\207Offer_Python/43.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.py" @@ -1,4 +1,4 @@ -# 颠倒两个字符串区间的位置 -class Solution: - def LeftRotateString(self, s, n): +# 颠倒两个字符串区间的位置 +class Solution: + def LeftRotateString(self, s, n): return s[n:] + s[:n] \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/44.\347\277\273\350\275\254\345\215\225\350\257\215\351\241\272\345\272\217\345\210\227.py" "b/\345\211\221\346\214\207Offer_Python/44.\347\277\273\350\275\254\345\215\225\350\257\215\351\241\272\345\272\217\345\210\227.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/44.\347\277\273\350\275\254\345\215\225\350\257\215\351\241\272\345\272\217\345\210\227.py" rename to "\345\211\221\346\214\207Offer_Python/44.\347\277\273\350\275\254\345\215\225\350\257\215\351\241\272\345\272\217\345\210\227.py" index 1246a6b..06d5b7c 100644 --- "a/\345\211\221\346\214\207Offer/44.\347\277\273\350\275\254\345\215\225\350\257\215\351\241\272\345\272\217\345\210\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/44.\347\277\273\350\275\254\345\215\225\350\257\215\351\241\272\345\272\217\345\210\227.py" @@ -1,5 +1,5 @@ -# 字符串按空格切分成数组,反转数组后按空格分隔组成字符串 -class Solution: - def ReverseSentence(self, s): - l = s.split(' ') +# 字符串按空格切分成数组,反转数组后按空格分隔组成字符串 +class Solution: + def ReverseSentence(self, s): + l = s.split(' ') return ' '.join(l[::-1]) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/45.\346\211\221\345\205\213\347\211\214\351\241\272\345\255\220.py" "b/\345\211\221\346\214\207Offer_Python/45.\346\211\221\345\205\213\347\211\214\351\241\272\345\255\220.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/45.\346\211\221\345\205\213\347\211\214\351\241\272\345\255\220.py" rename to "\345\211\221\346\214\207Offer_Python/45.\346\211\221\345\205\213\347\211\214\351\241\272\345\255\220.py" index 040b73b..4eb5b9c 100644 --- "a/\345\211\221\346\214\207Offer/45.\346\211\221\345\205\213\347\211\214\351\241\272\345\255\220.py" +++ "b/\345\211\221\346\214\207Offer_Python/45.\346\211\221\345\205\213\347\211\214\351\241\272\345\255\220.py" @@ -1,14 +1,14 @@ -class Solution: - def IsContinuous(self, numbers): - if len(numbers) != 5: - return False - numbers.sort() - while 0 in numbers: - numbers.remove(0) - for i,v in enumerate(numbers): - # 牌重复 - if v in numbers[i+1:]: - return False - # 顺子区间在5以内 - if numbers[-1]-numbers[0] < 5: +class Solution: + def IsContinuous(self, numbers): + if len(numbers) != 5: + return False + numbers.sort() + while 0 in numbers: + numbers.remove(0) + for i,v in enumerate(numbers): + # 牌重复 + if v in numbers[i+1:]: + return False + # 顺子区间在5以内 + if numbers[-1]-numbers[0] < 5: return True \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/46.\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260).py" "b/\345\211\221\346\214\207Offer_Python/46.\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260).py" similarity index 97% rename from "\345\211\221\346\214\207Offer/46.\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260).py" rename to "\345\211\221\346\214\207Offer_Python/46.\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260).py" index a1a306c..d878cb2 100644 --- "a/\345\211\221\346\214\207Offer/46.\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260).py" +++ "b/\345\211\221\346\214\207Offer_Python/46.\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260).py" @@ -1,28 +1,28 @@ -# 方法一:使用栈 -class Solution: - def LastRemaining_Solution(self, n, m): - if n < 1: - return -1 - i = 0 - nums = range(n) - while len(nums) > 1: - i = (m - 1 + i) % len(nums) - nums.pop(i) - return nums[0] - -# 方法二:使用两个数组,一个用于判断,一个用于删除指定元素 -# 每一轮中一个数组用来判断出列的元素,另一个数组则删除该元素,一轮结束后将删除后的数组复制给判断的数组,进入新的一轮 -class Solution: - def LastRemaining_Solution(self, n, m): - if n < 1: - return -1 - a = [i for i in range(n)] - b = a[:] - count = 1 - while len(a)>1: - for i in range(len(a)): - if count%m == 0: - b.remove(a[i]) - count += 1 - a = b[:] +# 方法一:使用栈 +class Solution: + def LastRemaining_Solution(self, n, m): + if n < 1: + return -1 + i = 0 + nums = range(n) + while len(nums) > 1: + i = (m - 1 + i) % len(nums) + nums.pop(i) + return nums[0] + +# 方法二:使用两个数组,一个用于判断,一个用于删除指定元素 +# 每一轮中一个数组用来判断出列的元素,另一个数组则删除该元素,一轮结束后将删除后的数组复制给判断的数组,进入新的一轮 +class Solution: + def LastRemaining_Solution(self, n, m): + if n < 1: + return -1 + a = [i for i in range(n)] + b = a[:] + count = 1 + while len(a)>1: + for i in range(len(a)): + if count%m == 0: + b.remove(a[i]) + count += 1 + a = b[:] return a[0] \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/47.\346\261\2021+2+3+...+n.py" "b/\345\211\221\346\214\207Offer_Python/47.\346\261\2021+2+3+...+n.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/47.\346\261\2021+2+3+...+n.py" rename to "\345\211\221\346\214\207Offer_Python/47.\346\261\2021+2+3+...+n.py" index bc77d5b..c89026d 100644 --- "a/\345\211\221\346\214\207Offer/47.\346\261\2021+2+3+...+n.py" +++ "b/\345\211\221\346\214\207Offer_Python/47.\346\261\2021+2+3+...+n.py" @@ -1,6 +1,6 @@ -# 类似阶乘 -class Solution: - def Sum_Solution(self, n): - if n == 1: - return 1 +# 类似阶乘 +class Solution: + def Sum_Solution(self, n): + if n == 1: + return 1 return self.Sum_Solution(n-1) + n \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/48.\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" "b/\345\211\221\346\214\207Offer_Python/48.\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/48.\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" rename to "\345\211\221\346\214\207Offer_Python/48.\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" index 8cfc3f2..9e18a8f 100644 --- "a/\345\211\221\346\214\207Offer/48.\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" +++ "b/\345\211\221\346\214\207Offer_Python/48.\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" @@ -1,7 +1,7 @@ -# 利用sum()函数 -class Solution: - def Add(self, num1, num2): - s = [] - s.append(num1) - s.append(num2) +# 利用sum()函数 +class Solution: + def Add(self, num1, num2): + s = [] + s.append(num1) + s.append(num2) return sum(s) \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/49.\346\212\212\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\210\220\346\225\264\346\225\260.py" "b/\345\211\221\346\214\207Offer_Python/49.\346\212\212\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\210\220\346\225\264\346\225\260.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/49.\346\212\212\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\210\220\346\225\264\346\225\260.py" rename to "\345\211\221\346\214\207Offer_Python/49.\346\212\212\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\210\220\346\225\264\346\225\260.py" index b58d090..ba5f5e9 100644 --- "a/\345\211\221\346\214\207Offer/49.\346\212\212\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\210\220\346\225\264\346\225\260.py" +++ "b/\345\211\221\346\214\207Offer_Python/49.\346\212\212\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\210\220\346\225\264\346\225\260.py" @@ -1,7 +1,7 @@ -# 字符串是合法数值时可转换为整数,否则抛异常 -class Solution: - def StrToInt(self, s): - try: - return int(s) - except: +# 字符串是合法数值时可转换为整数,否则抛异常 +class Solution: + def StrToInt(self, s): + try: + return int(s) + except: return 0 \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/50.\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227.py" "b/\345\211\221\346\214\207Offer_Python/50.\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/50.\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227.py" rename to "\345\211\221\346\214\207Offer_Python/50.\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227.py" index a6e79fd..0b5d365 100644 --- "a/\345\211\221\346\214\207Offer/50.\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227.py" +++ "b/\345\211\221\346\214\207Offer_Python/50.\346\225\260\347\273\204\344\270\255\351\207\215\345\244\215\347\232\204\346\225\260\345\255\227.py" @@ -1,21 +1,21 @@ -# 方法一:列表的count()方法 -class Solution: - # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] - # 函数返回True/False - def duplicate(self, numbers, duplication): - for i in numbers: - if numbers.count(i)>1: - duplication[0] = i - return True - return False - -# 方法二:集合的Counter对象,返回键值对,键是元素,值是元素个数 -import collections -class Solution: - def duplicate(self, numbers, duplication): - c = collections.Counter(numbers) - for value,num in c.items(): - if num>1: - duplication[0] = value - return True +# 方法一:列表的count()方法 +class Solution: + # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] + # 函数返回True/False + def duplicate(self, numbers, duplication): + for i in numbers: + if numbers.count(i)>1: + duplication[0] = i + return True + return False + +# 方法二:集合的Counter对象,返回键值对,键是元素,值是元素个数 +import collections +class Solution: + def duplicate(self, numbers, duplication): + c = collections.Counter(numbers) + for value,num in c.items(): + if num>1: + duplication[0] = value + return True return False \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/51.\346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204.py" "b/\345\211\221\346\214\207Offer_Python/51.\346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/51.\346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204.py" rename to "\345\211\221\346\214\207Offer_Python/51.\346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204.py" index 7dd5e13..16747c0 100644 --- "a/\345\211\221\346\214\207Offer/51.\346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204.py" +++ "b/\345\211\221\346\214\207Offer_Python/51.\346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204.py" @@ -1,10 +1,10 @@ -# 不要将索引相同的元素算进因子即可 -class Solution: - def multiply(self, A): - n = len(A) - B = [1]*n - for i in range(n): - for j in range(n): - if i != j: - B[i] *= A[j] +# 不要将索引相同的元素算进因子即可 +class Solution: + def multiply(self, A): + n = len(A) + B = [1]*n + for i in range(n): + for j in range(n): + if i != j: + B[i] *= A[j] return B \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/52.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215.py" "b/\345\211\221\346\214\207Offer_Python/52.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215.py" similarity index 98% rename from "\345\211\221\346\214\207Offer/52.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215.py" rename to "\345\211\221\346\214\207Offer_Python/52.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215.py" index cf3d5ab..270fd42 100644 --- "a/\345\211\221\346\214\207Offer/52.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215.py" +++ "b/\345\211\221\346\214\207Offer_Python/52.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215.py" @@ -1,19 +1,19 @@ -class Solution: - def match(self, s, pattern): - if not s and not pattern: - return True - if s and not pattern: - return False - # 第二个字符为* p=a* - if len(pattern)>1 and pattern[1]=='*': - # 第一个字符匹配 s=a p=a*或p=.* - if len(s)>0 and (s[0]==pattern[0] or pattern[0]=='.'): - # *表示出现0次 *表示出现1次 *表示出现多次 - return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern) - # 第一个字符不匹配 - else: - return self.match(s, pattern[2:]) - # 第二个字符不为*,且第一个字符匹配 - if len(s)>0 and (s[0]==pattern[0] or pattern[0]=='.'): - return self.match(s[1:], pattern[1:]) +class Solution: + def match(self, s, pattern): + if not s and not pattern: + return True + if s and not pattern: + return False + # 第二个字符为* p=a* + if len(pattern)>1 and pattern[1]=='*': + # 第一个字符匹配 s=a p=a*或p=.* + if len(s)>0 and (s[0]==pattern[0] or pattern[0]=='.'): + # *表示出现0次 *表示出现1次 *表示出现多次 + return self.match(s, pattern[2:]) or self.match(s[1:], pattern[2:]) or self.match(s[1:], pattern) + # 第一个字符不匹配 + else: + return self.match(s, pattern[2:]) + # 第二个字符不为*,且第一个字符匹配 + if len(s)>0 and (s[0]==pattern[0] or pattern[0]=='.'): + return self.match(s[1:], pattern[1:]) return False \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/53.\350\241\250\347\244\272\346\225\260\345\200\274\347\232\204\345\255\227\347\254\246\344\270\262.py" "b/\345\211\221\346\214\207Offer_Python/53.\350\241\250\347\244\272\346\225\260\345\200\274\347\232\204\345\255\227\347\254\246\344\270\262.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/53.\350\241\250\347\244\272\346\225\260\345\200\274\347\232\204\345\255\227\347\254\246\344\270\262.py" rename to "\345\211\221\346\214\207Offer_Python/53.\350\241\250\347\244\272\346\225\260\345\200\274\347\232\204\345\255\227\347\254\246\344\270\262.py" index 774dee5..fcdbf08 100644 --- "a/\345\211\221\346\214\207Offer/53.\350\241\250\347\244\272\346\225\260\345\200\274\347\232\204\345\255\227\347\254\246\344\270\262.py" +++ "b/\345\211\221\346\214\207Offer_Python/53.\350\241\250\347\244\272\346\225\260\345\200\274\347\232\204\345\255\227\347\254\246\344\270\262.py" @@ -1,8 +1,8 @@ -# 能表示数值的字符串能够转为浮点类型,否则抛异常 -class Solution: - def isNumeric(self, s): - try: - float(s) - return True - except: +# 能表示数值的字符串能够转为浮点类型,否则抛异常 +class Solution: + def isNumeric(self, s): + try: + float(s) + return True + except: return False \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/54.\345\255\227\347\254\246\346\265\201\344\270\255\347\254\254\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\255\227\347\254\246.py" "b/\345\211\221\346\214\207Offer_Python/54.\345\255\227\347\254\246\346\265\201\344\270\255\347\254\254\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\255\227\347\254\246.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/54.\345\255\227\347\254\246\346\265\201\344\270\255\347\254\254\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\255\227\347\254\246.py" rename to "\345\211\221\346\214\207Offer_Python/54.\345\255\227\347\254\246\346\265\201\344\270\255\347\254\254\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\255\227\347\254\246.py" index 40d968f..1d0920e 100644 --- "a/\345\211\221\346\214\207Offer/54.\345\255\227\347\254\246\346\265\201\344\270\255\347\254\254\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\255\227\347\254\246.py" +++ "b/\345\211\221\346\214\207Offer_Python/54.\345\255\227\347\254\246\346\265\201\344\270\255\347\254\254\344\270\200\344\270\252\344\270\215\351\207\215\345\244\215\347\232\204\345\255\227\347\254\246.py" @@ -1,13 +1,13 @@ -# 使用全局数组或字符串保存字符流 -class Solution: - def __init__(self): - self.l = [] - # self.s = '' - def FirstAppearingOnce(self): - for i in self.l: - if self.l.count(i)==1: - return i - return '#' - def Insert(self, char): - self.l.append(char) +# 使用全局数组或字符串保存字符流 +class Solution: + def __init__(self): + self.l = [] + # self.s = '' + def FirstAppearingOnce(self): + for i in self.l: + if self.l.count(i)==1: + return i + return '#' + def Insert(self, char): + self.l.append(char) # self.s += char \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/55.\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.py" "b/\345\211\221\346\214\207Offer_Python/55.\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/55.\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.py" rename to "\345\211\221\346\214\207Offer_Python/55.\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.py" index c08241c..d760c26 100644 --- "a/\345\211\221\346\214\207Offer/55.\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/55.\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.py" @@ -1,9 +1,9 @@ -# 用数组存放链表结点值,如果重复了则该结点就是入口结点 -class Solution: - def EntryNodeOfLoop(self, pHead): - l = [] - while pHead: - if pHead in l: - return pHead - l.append(pHead) +# 用数组存放链表结点值,如果重复了则该结点就是入口结点 +class Solution: + def EntryNodeOfLoop(self, pHead): + l = [] + while pHead: + if pHead in l: + return pHead + l.append(pHead) pHead = pHead.next \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/56.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\351\207\215\345\244\215\347\232\204\347\273\223\347\202\271.py" "b/\345\211\221\346\214\207Offer_Python/56.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\351\207\215\345\244\215\347\232\204\347\273\223\347\202\271.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/56.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\351\207\215\345\244\215\347\232\204\347\273\223\347\202\271.py" rename to "\345\211\221\346\214\207Offer_Python/56.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\351\207\215\345\244\215\347\232\204\347\273\223\347\202\271.py" index 82b278a..4c45339 100644 --- "a/\345\211\221\346\214\207Offer/56.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\351\207\215\345\244\215\347\232\204\347\273\223\347\202\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/56.\345\210\240\351\231\244\351\223\276\350\241\250\344\270\255\351\207\215\345\244\215\347\232\204\347\273\223\347\202\271.py" @@ -1,14 +1,14 @@ -# 用数组存放结点值,再统计结点个数,将个数为1的结点链接成链表 -class Solution: - def deleteDuplication(self, pHead): - l = [] - while pHead: - l.append(pHead.val) - pHead = pHead.next - res = ListNode(None) - head = res - for i in l: - if l.count(i)==1: - head.next = ListNode(i) - head = head.next +# 用数组存放结点值,再统计结点个数,将个数为1的结点链接成链表 +class Solution: + def deleteDuplication(self, pHead): + l = [] + while pHead: + l.append(pHead.val) + pHead = pHead.next + res = ListNode(None) + head = res + for i in l: + if l.count(i)==1: + head.next = ListNode(i) + head = head.next return res.next \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/57.\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" "b/\345\211\221\346\214\207Offer_Python/57.\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/57.\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" rename to "\345\211\221\346\214\207Offer_Python/57.\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" index f00fbd2..fba257e 100644 --- "a/\345\211\221\346\214\207Offer/57.\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/57.\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" @@ -1,21 +1,21 @@ -# 中序遍历:左根右 -class Solution: - def GetNext(self, pNode): - if not pNode: - return None - # 如果当前结点有右子树,那么下个结点就是右子树最左边的结点 - if pNode.right: - pNext = pNode.right - while pNext.left: - pNext = pNext.left - return pNext - # 当前结点有下一个结点时 - while pNode.next: - temp = pNode.next - # 如果当前结点是父节点左孩子,那么父节点就是下一个节点 - if temp.left==pNode: - return temp - # 将父节点赋给当前结点,直到当前结点是其父节点的左孩子位置 - pNode = temp - # 当前结点是尾结点 +# 中序遍历:左根右 +class Solution: + def GetNext(self, pNode): + if not pNode: + return None + # 如果当前结点有右子树,那么下个结点就是右子树最左边的结点 + if pNode.right: + pNext = pNode.right + while pNext.left: + pNext = pNext.left + return pNext + # 当前结点有下一个结点时 + while pNode.next: + temp = pNode.next + # 如果当前结点是父节点左孩子,那么父节点就是下一个节点 + if temp.left==pNode: + return temp + # 将父节点赋给当前结点,直到当前结点是其父节点的左孩子位置 + pNode = temp + # 当前结点是尾结点 return None \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/58.\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221.py" "b/\345\211\221\346\214\207Offer_Python/58.\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/58.\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221.py" rename to "\345\211\221\346\214\207Offer_Python/58.\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221.py" index b19135b..ee2635d 100644 --- "a/\345\211\221\346\214\207Offer/58.\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221.py" +++ "b/\345\211\221\346\214\207Offer_Python/58.\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221.py" @@ -1,62 +1,62 @@ -# 判断左右子树对称的两个结点是否相同 -# 嵌套方法写法 -class Solution: - def isSymmetrical(self, pRoot): - def isSameTree(p, q): - if not p and not q: - return True - if p and q and p.val==q.val: - l = isSameTree(p.left, q.right) - r = isSameTree(p.right, q.left) - return l and r - else: - return False - - if not pRoot: - return True - return isSameTree(pRoot.left, pRoot.right) - -# 单独调用写法 -class Solution: - def isSymmetrical(self, pRoot): - if not pRoot: - return True - return self.isSameTree(pRoot.left, pRoot.right) - - def isSameTree(self, p, q): - if not p and not q: - return True - if p and q and p.val==q.val: - l = self.isSameTree(p.left, q.right) - r = self.isSameTree(p.right, q.left) - return l and r - return False - -################################ 递归思路 ######################################## - # 1、极简化方法作用 - # 2、先只处理 “无” 与 “1” 的情况 - # 3、再处理用 “2”或“3” 代表 “多” 的情况,含有相同需求或逻辑则使用递归处理 - - # 方法作用极简化:判断两个结点是否相同 - def isSameTree(self, p, q): - # 没有结点的情况 - if not p and not q: - return True - # 各1个结点且相等的情况 - if p and q and p.val==q.val: - return True - # 其他 - return False - - def isSameTree(self, p, q): - # 没有结点的情况 - if not p and not q: - return True - # 结点含有左右子结点的情况。各1个结点且相等的情况可合并,故省略 - if p and q and p.val==q.val: - # 需要再判断各自左右结点是否相同,使用递归 - l = self.isSameTree(p.left, q.right) - r = self.isSameTree(p.right, q.left) - return l and r - # 其他 +# 判断左右子树对称的两个结点是否相同 +# 嵌套方法写法 +class Solution: + def isSymmetrical(self, pRoot): + def isSameTree(p, q): + if not p and not q: + return True + if p and q and p.val==q.val: + l = isSameTree(p.left, q.right) + r = isSameTree(p.right, q.left) + return l and r + else: + return False + + if not pRoot: + return True + return isSameTree(pRoot.left, pRoot.right) + +# 单独调用写法 +class Solution: + def isSymmetrical(self, pRoot): + if not pRoot: + return True + return self.isSameTree(pRoot.left, pRoot.right) + + def isSameTree(self, p, q): + if not p and not q: + return True + if p and q and p.val==q.val: + l = self.isSameTree(p.left, q.right) + r = self.isSameTree(p.right, q.left) + return l and r + return False + +################################ 递归思路 ######################################## + # 1、极简化方法作用 + # 2、先只处理 “无” 与 “1” 的情况 + # 3、再处理用 “2”或“3” 代表 “多” 的情况,含有相同需求或逻辑则使用递归处理 + + # 方法作用极简化:判断两个结点是否相同 + def isSameTree(self, p, q): + # 没有结点的情况 + if not p and not q: + return True + # 各1个结点且相等的情况 + if p and q and p.val==q.val: + return True + # 其他 + return False + + def isSameTree(self, p, q): + # 没有结点的情况 + if not p and not q: + return True + # 结点含有左右子结点的情况。各1个结点且相等的情况可合并,故省略 + if p and q and p.val==q.val: + # 需要再判断各自左右结点是否相同,使用递归 + l = self.isSameTree(p.left, q.right) + r = self.isSameTree(p.right, q.left) + return l and r + # 其他 return False \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/59.\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" "b/\345\211\221\346\214\207Offer_Python/59.\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" similarity index 96% rename from "\345\211\221\346\214\207Offer/59.\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" rename to "\345\211\221\346\214\207Offer_Python/59.\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" index 0ed7184..2d5d891 100644 --- "a/\345\211\221\346\214\207Offer/59.\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" +++ "b/\345\211\221\346\214\207Offer_Python/59.\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221.py" @@ -1,26 +1,26 @@ -# cur_list:存放当前行结点 -# next_list:存放下一行结点 -# level:存放当前行的值 -# res:存放所有行的值 -# flag:反复判断奇偶行 -class Solution: - def Print(self, pRoot): - if not pRoot: - return [] - cur_list, next_list, level, res = [pRoot], [], [], [] - flag = 0 - while cur_list: - for i in cur_list: - level.append(i.val) - if i.left: - next_list.append(i.left) - if i.right: - next_list.append(i.right) - if flag: - flag = 0 - level.reverse() - else: - flag = 1 - res.append(level) - cur_list, next_list, level = next_list, [], [] +# cur_list:存放当前行结点 +# next_list:存放下一行结点 +# level:存放当前行的值 +# res:存放所有行的值 +# flag:反复判断奇偶行 +class Solution: + def Print(self, pRoot): + if not pRoot: + return [] + cur_list, next_list, level, res = [pRoot], [], [], [] + flag = 0 + while cur_list: + for i in cur_list: + level.append(i.val) + if i.left: + next_list.append(i.left) + if i.right: + next_list.append(i.right) + if flag: + flag = 0 + level.reverse() + else: + flag = 1 + res.append(level) + cur_list, next_list, level = next_list, [], [] return res \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/60.\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214.py" "b/\345\211\221\346\214\207Offer_Python/60.\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/60.\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214.py" rename to "\345\211\221\346\214\207Offer_Python/60.\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214.py" index c43a720..af8d31e 100644 --- "a/\345\211\221\346\214\207Offer/60.\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214.py" +++ "b/\345\211\221\346\214\207Offer_Python/60.\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214.py" @@ -1,20 +1,20 @@ -# cur_list:存放当前行结点 -# next_list:存放下一行结点 -# level:存放当前行的值 -# res:存放所有行的值 -class Solution: - # 返回二维列表[[1,2],[4,5]] - def Print(self, pRoot): - if not pRoot: - return [] - cur_list, next_list, level, res = [pRoot], [], [], [] - while cur_list: - for i in cur_list: - level.append(i.val) - if i.left: - next_list.append(i.left) - if i.right: - next_list.append(i.right) - res.append(level) - cur_list, next_list, level = next_list, [], [] +# cur_list:存放当前行结点 +# next_list:存放下一行结点 +# level:存放当前行的值 +# res:存放所有行的值 +class Solution: + # 返回二维列表[[1,2],[4,5]] + def Print(self, pRoot): + if not pRoot: + return [] + cur_list, next_list, level, res = [pRoot], [], [], [] + while cur_list: + for i in cur_list: + level.append(i.val) + if i.left: + next_list.append(i.left) + if i.right: + next_list.append(i.right) + res.append(level) + cur_list, next_list, level = next_list, [], [] return res \ No newline at end of file diff --git "a/\345\211\221\346\214\207Offer/61.\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221.py" "b/\345\211\221\346\214\207Offer_Python/61.\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/61.\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221.py" rename to "\345\211\221\346\214\207Offer_Python/61.\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221.py" index 9085fb5..07154b3 100644 --- "a/\345\211\221\346\214\207Offer/61.\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221.py" +++ "b/\345\211\221\346\214\207Offer_Python/61.\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221.py" @@ -1,81 +1,81 @@ -class Solution: - - def __init__(self): - self.flag = -1 - - def Serialize(self, root): - if not root: - return '#,' - return str(root.val) + ',' + self.Serialize(root.left) + self.Serialize(root.right) - - # if 写法一 - def Deserialize(self, s): - self.flag += 1 - l = s.split(',') - if l[self.flag] == '#': - return None - root = TreeNode(int(l[self.flag])) - root.left = self.Deserialize(s) - root.right = self.Deserialize(s) - return root - - # if 写法二 - def Deserialize(self, s): - self.flag += 1 - l = s.split(',') - root = None - if l[self.flag] != '#': - root = TreeNode(int(l[self.flag])) - root.left = self.Deserialize(s) - root.right = self.Deserialize(s) - return root - -################################### 解释递归 ############################################## - -# 序列化:将二叉树转为字符序列 -# 反序列化:将字符序列转为二叉树 -class Solution: - def __init__(self): - # 通过全局变量flag来迭代序列的值 - self.flag = -1 - - - - # 方法作用极简化:将一个结点转为 “ 结点值,” 的形式 - def Serialize(self, root): - # 没有结点的情况 - if not root: - return '#,' - # 1个结点的情况 - return str(root.val) + ',' - - def Serialize(self, root): - if not root: - return '#,' - # 1个结点的情况可合并到多个结点的情况,故省略 - # 2个或3个结点代表多个结点的情况。左右结点也需要转为 “ 结点值,” 的形式则递归调用,最后将各自转化结果拼接成字符串返回 - return str(root.val) + ',' + self.Serialize(root.left) + self.Serialize(root.right) - - - - # 方法作用极简化:将序列的一个值转化为一个结点 - def Deserialize(self, s): - l = s.split(',') - # 表示树为空的情况 - if l[0] == '#': - return None - # 1个结点的情况 - root = TreeNode(int(l[0])) - return root - - def Deserialize(self, s): - # 每次遍历序列都要迭代下一个值,引入全局变量flag - self.flag += 1 - l = s.split(',') - if l[self.flag] == '#': - return None - root = TreeNode(int(l[self.flag])) - # 2个或3个结点代表多个结点的情况。左右结点也需要将序列的一个值转化为一个结点则递归调用 - root.left = self.Deserialize(s) - root.right = self.Deserialize(s) - return root +class Solution: + + def __init__(self): + self.flag = -1 + + def Serialize(self, root): + if not root: + return '#,' + return str(root.val) + ',' + self.Serialize(root.left) + self.Serialize(root.right) + + # if 写法一 + def Deserialize(self, s): + self.flag += 1 + l = s.split(',') + if l[self.flag] == '#': + return None + root = TreeNode(int(l[self.flag])) + root.left = self.Deserialize(s) + root.right = self.Deserialize(s) + return root + + # if 写法二 + def Deserialize(self, s): + self.flag += 1 + l = s.split(',') + root = None + if l[self.flag] != '#': + root = TreeNode(int(l[self.flag])) + root.left = self.Deserialize(s) + root.right = self.Deserialize(s) + return root + +################################### 解释递归 ############################################## + +# 序列化:将二叉树转为字符序列 +# 反序列化:将字符序列转为二叉树 +class Solution: + def __init__(self): + # 通过全局变量flag来迭代序列的值 + self.flag = -1 + + + + # 方法作用极简化:将一个结点转为 “ 结点值,” 的形式 + def Serialize(self, root): + # 没有结点的情况 + if not root: + return '#,' + # 1个结点的情况 + return str(root.val) + ',' + + def Serialize(self, root): + if not root: + return '#,' + # 1个结点的情况可合并到多个结点的情况,故省略 + # 2个或3个结点代表多个结点的情况。左右结点也需要转为 “ 结点值,” 的形式则递归调用,最后将各自转化结果拼接成字符串返回 + return str(root.val) + ',' + self.Serialize(root.left) + self.Serialize(root.right) + + + + # 方法作用极简化:将序列的一个值转化为一个结点 + def Deserialize(self, s): + l = s.split(',') + # 表示树为空的情况 + if l[0] == '#': + return None + # 1个结点的情况 + root = TreeNode(int(l[0])) + return root + + def Deserialize(self, s): + # 每次遍历序列都要迭代下一个值,引入全局变量flag + self.flag += 1 + l = s.split(',') + if l[self.flag] == '#': + return None + root = TreeNode(int(l[self.flag])) + # 2个或3个结点代表多个结点的情况。左右结点也需要将序列的一个值转化为一个结点则递归调用 + root.left = self.Deserialize(s) + root.right = self.Deserialize(s) + return root diff --git "a/\345\211\221\346\214\207Offer/62.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.py" "b/\345\211\221\346\214\207Offer_Python/62.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.py" similarity index 97% rename from "\345\211\221\346\214\207Offer/62.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.py" rename to "\345\211\221\346\214\207Offer_Python/62.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.py" index 122b9b2..2296e04 100644 --- "a/\345\211\221\346\214\207Offer/62.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.py" +++ "b/\345\211\221\346\214\207Offer_Python/62.\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.py" @@ -1,15 +1,15 @@ -# 中序遍历二叉搜索树,将遍历结点值存放在数组中,得到由小到大排序的数组 -class Solution: - def KthNode(self, pRoot, k): - global res - res = [] - self.midNode(pRoot) - if k<=0 or len(res)=0 and matrix[(i-1)*cols+j]==path[0]: - return self.find(matrix,rows,cols,path[1:],i-1,j) - elif i+1=0 and matrix[i*cols+j-1]==path[0]: - return self.find(matrix,rows,cols,path[1:],i,j-1) - elif j+1=0 and matrix[(i-1)*cols+j]==path[0]: + return self.find(matrix,rows,cols,path[1:],i-1,j) + elif i+1=0 and matrix[i*cols+j-1]==path[0]: + return self.find(matrix,rows,cols,path[1:],i,j-1) + elif j+1 threshold: - return 0 - if row<0 or row>=rows or col<0 or col>=cols : - return 0 - if d.get((row,col)): - return 0 - else: - d[(row,col)]=1 - # 2到多个方格的情况 - return 1+self.stat(row+1,col,threshold,rows,cols)+self.stat(row-1,col,threshold,rows,cols)+self.stat(row,col+1,threshold,rows,cols)+self.stat(row,col-1,threshold,rows,cols) - -# 使用数组 -class Solution: - def __init__(self): - self.arr = [] - def movingCount(self, threshold, rows, cols): - return self.stat(0, 0, threshold, rows, cols) - def stat(self, row, col, threshold, rows, cols): - if row/10 + row%10 + col/10 + col%10 > threshold: - return 0 - if row<0 or row>=rows or col<0 or col>=cols: - return 0 - if (row,col) in self.arr: - return 0 - else: - self.arr.append((row,col)) +# 使用字典 +class Solution: + def movingCount(self, threshold, rows, cols): + global d + d={} + return self.stat(0,0,threshold, rows, cols) + def stat(self,row,col,threshold,rows,cols): + # 1个方格的情况 + if row/10 + row%10 + col/10 + col%10 > threshold: + return 0 + if row<0 or row>=rows or col<0 or col>=cols : + return 0 + if d.get((row,col)): + return 0 + else: + d[(row,col)]=1 + # 2到多个方格的情况 + return 1+self.stat(row+1,col,threshold,rows,cols)+self.stat(row-1,col,threshold,rows,cols)+self.stat(row,col+1,threshold,rows,cols)+self.stat(row,col-1,threshold,rows,cols) + +# 使用数组 +class Solution: + def __init__(self): + self.arr = [] + def movingCount(self, threshold, rows, cols): + return self.stat(0, 0, threshold, rows, cols) + def stat(self, row, col, threshold, rows, cols): + if row/10 + row%10 + col/10 + col%10 > threshold: + return 0 + if row<0 or row>=rows or col<0 or col>=cols: + return 0 + if (row,col) in self.arr: + return 0 + else: + self.arr.append((row,col)) return 1 + self.stat(row+1, col, threshold, rows, cols) + self.stat(row-1, col, threshold, rows, cols) + self.stat(row, col+1, threshold, rows, cols) + self.stat(row, col-1, threshold, rows, cols) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/README.md" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/README.md" deleted file mode 100644 index 7996cbb..0000000 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/README.md" +++ /dev/null @@ -1 +0,0 @@ -附:[十大经典排序算法动画与解析](https://mp.weixin.qq.com/s/vn3KiV-ez79FmbZ36SX9lg) diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bubble.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bubble.java" index b1d93af..357ab75 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bubble.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bubble.java" @@ -1,14 +1,16 @@ package sort; -// 冒泡排序 +/* +冒泡排序: +1、第一个for循环表示外循环次数,将所有元素都排序需要的循环次数 + 第二个for循环表示内循环次数,将一个元素排序需要的循环次数。一轮循环中从左到右将一个大数交换到后面 +2、flag标记一次排序过程是否发生元素位置交换,若没有交换说明已经排序好了,直接结束 + */ public class Bubble { public int[] bubbleSort(int[] nums) { int n = nums.length; - // 外循环次数 for (int i = 0; i < n - 1; i++) { - // 标记一次排序过程是否发生元素位置交换 boolean flag = true; - // 内循环次数 for (int j = 0; j < n - i - 1; j++) { if (nums[j] > nums[j + 1]) { int temp = nums[j]; @@ -17,7 +19,9 @@ public int[] bubbleSort(int[] nums) { flag = false; } } - if (flag) break; + if (flag) { + break; + } } return nums; } @@ -26,7 +30,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Bubble bubble = new Bubble(); nums = bubble.bubbleSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bucket.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bucket.java" index 08ae06f..e19569c 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bucket.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Bucket.java" @@ -2,28 +2,28 @@ import java.util.Arrays; -// 桶排序 +/* +桶排序: +1、获取数组最大值、最小值,以数值范围定义桶数组stats大小,数组默认值为0 +2、以数值个数定义结果数组res大小,数组默认值为0 +3、遍历元素,映射到桶中,统计每个数的出现次数 +4、遍历每个桶,按序获取数字放到结果数组 + */ public class Bucket { public int[] bucketSort(int[] nums) { - // 获取数组最大值、最小值 int max = Arrays.stream(nums).max().getAsInt(); int min = Arrays.stream(nums).min().getAsInt(); - - // 以数值范围定义数组大小 int[] stats = new int[max - min + 1]; - Arrays.fill(stats, 0); - // 以数值个数定义的数组大小 int[] res = new int[nums.length]; - Arrays.fill(res, 0); - - // 统计每个数的出现次数 - for(int num : nums) + for(int num : nums) { stats[num - min]++; - // 遍历每个桶,按序获取数字放到结果数组 + } int k = 0; - for (int i = 0; i < stats.length; i++) - for (int j = 0; j < stats[i]; j++) + for (int i = 0; i < stats.length; i++) { + for (int j = 0; j < stats[i]; j++) { res[k++] = min + i; + } + } return res; } @@ -31,7 +31,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Bucket bucket = new Bucket(); nums = bucket.bucketSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Count.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Count.java" index a0e8079..bf4a0ec 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Count.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Count.java" @@ -2,23 +2,26 @@ import java.util.Arrays; -// 计数排序 +/* +计数排序: +1、获取数组最大值、最小值,以数值范围定义桶数组stats大小,数组默认值为0 +2、以数值个数定义结果数组res大小,数组默认值为0 +3、遍历元素,映射到桶中,统计每个数的出现次数 +4、遍历桶,滚动累加,此时桶值表示包括当前元素 前面总共有多少个元素,即表示元素在结果数组中的索引位置 +5、遍历元素,映射到桶中获取元素的最终索引,将元素存入结果数组。桶中该元素的索引位置减1,表示下一个同样的元素存放的位置 + */ public class Count { public int[] countSort(int[] nums) { int max = Arrays.stream(nums).max().getAsInt(); int min = Arrays.stream(nums).min().getAsInt(); - int[] stats = new int[max - min + 1]; - Arrays.fill(stats, 0); int[] res = new int[nums.length]; - Arrays.fill(res, 0); - - for (int num : nums) + for (int num : nums) { stats[num - min]++; - // 记录每个数字存放的索引位置 - for (int i = 1; i < nums.length; i++) + } + for (int i = 1; i < stats.length; i++) { stats[i] += stats[i - 1]; - // 获取每个数字的最终索引并存入结果数组 + } for (int num : nums) { res[stats[num - min] - 1] = num; stats[num - min]--; @@ -31,7 +34,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Count count = new Count(); nums = count.countSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Heap.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Heap.java" index e94588a..bca632b 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Heap.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Heap.java" @@ -1,39 +1,67 @@ package sort; +/* +1、堆:堆本质上就是一棵完全二叉树,它的每一个节点都必须大于等于或者小于等于其子节点 +2、最大堆:每个节点都大于等于子树所有节点的堆称为最大堆 + 最小堆:每个节点都小于等于子树所有节点的堆称为最小堆 +3、数组存储堆,节点的索引关系如下 + 索引角度:起始索引为0,某个节点在数组中的索引为i,则其(直接看索引,好记) + 1)父节点索引:(i-1)/2 + 2)左子节点索引:2i+1 + 3)右子节点索引:2i+2 + 位置角度:起始位置为1,某个节点在数组中的位置为j,则其(换算了一遍,不好记) + 1)父节点索引:((j-1)-1)/2 = j/2-1 + 2)左子节点索引:2(j-1)+1 = 2j-1 + 3)右子节点索引:2(j-1)+2 = 2j + */ + + // 堆排序 +/* +最大堆排序思路: +1、先将普通数组调整成最大堆数组 +2、堆顶元素就是最大值,将堆顶元素交换到数组尾部,重新调整剩余数组元素为最大堆 +3、循环处理第2步,最终数组升序排序 + */ public class Heap { private int n; public int[] heapSort(int[] nums) { n = nums.length; - // 堆的构造需要跟子节点比较,所以从最后一个非叶子结点开始向上构造最大堆 - for (int i = n / 2 - 1; i >= 0; i--) - max_heapify(nums, i); + // 堆的构造需要跟子节点比较,所以从 最后一个非叶子结点(最后一个节点的父节点) 开始向上构造最大堆 + // 必须从下往上逐层调整,每一层小值向下浮动,大值交换上去,最终最大值会升到根节点 + for (int i = n / 2 - 1; i >= 0; i--) { + maxHeapify(nums, i); + } + // 在最大堆的基础上,只改变了一个元素,重新调整为最大堆只需进行一次小值向下浮动即可 while (n > 0) { - // 根节点与最后一个节点交换 + // 根节点与最后一个节点交换,最终形成升序排序 swap(nums, 0, n - 1); + // n控制着剩余可调整的数组元素范围,即堆顶元素交换到数组尾部后就不参与堆调整了 n--; - // 交换完调整最大堆,父子两两交换,把小值往下换,把最大值升到根节点 - max_heapify(nums, 0); + // 交换完重新调整成最大堆,父子两两交换,把小值往下换,把最大值升到根节点 + maxHeapify(nums, 0); } return nums; } - // 堆调整的逻辑:父节点与子节点较大者交换,最终最大值会升到根节点 - private void max_heapify(int[] nums, int root) { + // 方法作用:将小值向下浮动。即父节点与子节点较大者交换,并递归处理 + private void maxHeapify(int[] nums, int root) { int maxIndex = root; // 索引从0开始 int left = root * 2 + 1, right = root * 2 + 2; // 如果有左孩子,且左孩子大于父节点,则将最大指针指向左孩子 - if (left < n && nums[left] > nums[maxIndex]) + if (left < n && nums[left] > nums[maxIndex]) { maxIndex = left; + } // 如果有右孩子,且右孩子大于父节点和左孩子,则将最大指针指向右孩子 - if (right < n && nums[right] > nums[maxIndex]) + if (right < n && nums[right] > nums[maxIndex]) { maxIndex = right; - // 如果父节点不是最大值,则将父节点与最大值交换,并且递归调整与父节点交换的位置。 + } + // 如果父节点不是最大值,则将父节点与最大值交换,并且递归调整与父节点交换的位置 if (maxIndex != root) { swap(nums, maxIndex, root); - max_heapify(nums, maxIndex); + maxHeapify(nums, maxIndex); } } @@ -47,7 +75,94 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Heap heap = new Heap(); nums = heap.heapSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } + } +} + + +// 最大堆,升序排序,去注释 +public class Heap { + private int n; + + public int[] heapSort(int[] nums) { + n = nums.length; + for (int i = n / 2 - 1; i >= 0; i--) { + maxHeapify(nums, i); + } + while (n > 0) { + swap(nums, 0, n - 1); + n--; + maxHeapify(nums, 0); + } + return nums; + } + + private void maxHeapify(int[] nums, int root) { + int maxIndex = root; + int left = root * 2 + 1, right = root * 2 + 2; + if (left < n && nums[left] > nums[maxIndex]) { + maxIndex = left; + } + if (right < n && nums[right] > nums[maxIndex]) { + maxIndex = right; + } + if (maxIndex != root) { + swap(nums, maxIndex, root); + maxHeapify(nums, maxIndex); + } + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; + } +} + + +/* +最小堆排序思路: +1、先将普通数组调整成最小堆数组 +2、堆顶元素就是最小值,将堆顶元素交换到数组尾部,重新调整剩余数组元素为最小堆 +3、循环处理第2步,最终数组降序排序 + */ +// 最小堆,降序排序,去注释 +public class Heap { + private int n; + + public int[] heapSort(int[] nums) { + n = nums.length; + for (int i = n / 2 - 1; i >= 0; i--) { + minHeapify(nums, i); + } + while (n > 0) { + swap(nums, 0, n - 1); + n--; + minHeapify(nums, 0); + } + return nums; + } + + private void minHeapify(int[] nums, int root) { + int minIndex = root; + int left = root * 2 + 1, right = root * 2 + 2; + if (left < n && nums[left] < nums[minIndex]) { + minIndex = left; + } + if (right < n && nums[right] < nums[minIndex]) { + minIndex = right; + } + if (minIndex != root) { + swap(nums, minIndex, root); + minHeapify(nums, minIndex); + } + } + + private void swap(int[] nums, int x, int y) { + int temp = nums[x]; + nums[x] = nums[y]; + nums[y] = temp; } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Insert.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Insert.java" index ade2fb2..5cccb03 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Insert.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Insert.java" @@ -1,6 +1,11 @@ package sort; -// 插入排序 +/* +插入排序: +1、第一个for循环从左到右遍历要排序的元素,第二个for循环从右到左将要排序的元素进行交换排序 +2、i从1开始,j从i开始,条件j>0保证j-1不会越界 +2、元素比较结果不用交换时,左边元素已经排序,可结束本轮排序 + */ public class Insert { public int[] insertSort(int[] nums) { for (int i = 1; i < nums.length; i++) { @@ -10,7 +15,6 @@ public int[] insertSort(int[] nums) { nums[j] = nums[j - 1]; nums[j - 1] = temp; } else { - // 左边元素已经排序,本次比较若没有交换则可结束本轮排序 break; } } @@ -22,7 +26,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Insert insert = new Insert(); nums = insert.insertSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Merge.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Merge.java" index 93acd44..89c321c 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Merge.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Merge.java" @@ -2,12 +2,21 @@ import java.util.Arrays; -// 归并排序 +/* +归并排序:递归 +1、方法功能:入参是一个数组,返回排序后的数组 +2、终止条件:数组长度小于2时,返回该数组 +3、一个元素处理过程和返回结果:直接返回该数组 +4、递归调用:左半部分和右半部分数组同样需要排序,因此调用同样的方法 +5、递归顺序:当前数组排序 需要依赖 左半部分和右半部分数组,因此要先递归排序左半部分和右半部分数组 +6、使用递归调用结果和返回结果:将两个有序数组合并,返回最终的排序数组 + */ public class Merge { public int[] mergeSort(int[] nums) { int n = nums.length; - if (n < 2) + if (n < 2) { return nums; + } int mid = n / 2; // 递归拆分数组 int[] left = mergeSort(Arrays.copyOfRange(nums, 0, mid)); @@ -15,18 +24,19 @@ public int[] mergeSort(int[] nums) { return combine(left, right); } - // 将两个数组排序合并为一个数组 + // 将两个有序数组合并为一个排序数组 private int[] combine(int[] left, int[] right) { int[] res = new int[left.length + right.length]; for (int i = 0, l = 0, r = 0; i < res.length; i++) { - if (l >= left.length) + if (l >= left.length) { res[i] = right[r++]; - else if (r >= right.length) + } else if (r >= right.length) { res[i] = left[l++]; - else if (left[l] > right[r]) - res[i] = right[r++]; - else + } else if (left[l] < right[r]) { res[i] = left[l++]; + } else { + res[i] = right[r++]; + } } return res; } @@ -35,7 +45,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Merge merge = new Merge(); nums = merge.mergeSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Quick.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Quick.java" index 8d8da25..4cc5f68 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Quick.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Quick.java" @@ -1,18 +1,53 @@ package sort; -// 快速排序 +/* +快速排序: +1、一次排序操作将返回一个已经排好位置的中点索引mid,该索引左边的元素都小于它,右边的元素都大于等于它 +2、递归方法: + 1)方法功能:根据数组和指定左右边界,进行一次排序,然后返回排序后的数组 + 2)终止条件:左边界大于等于右边界,说明只剩一个元素或边界无效,不用排序,直接返回数组 + 3)递归逻辑:排序好的中点的左半部分和右半部分数组也需要同样的操作,调用同样的方法进行排序。数组是引用类型,不用接收递归方法返回值,最后直接返回数组即可 + */ + +/* +一次排序初始: + 3 2 3 1 2 4 5 5 6 + ↑ ↑ ↑ + left index/i right +============================================================ +一次排序遍历交换过程: + 3 2 3 1 2 4 5 5 6 + ↑ ↑ ↑ ↑ + left index i right +============================================================ +一次排序遍历结束,准备交换中点,index-1表示最后一个值小于left的索引: + 3 2 1 2 3 4 5 5 6 + ↑ ↑ ↑ ↑ ↑ + left index-1 index right i +============================================================ +一次排序结果: + 2 2 1 3 3 4 5 5 6 + ↑ + mid +============================================================ +下一次排序: + 2 2 1 3 3 4 5 5 6 + ↑ ↑ ↑ ↑ ↑ + left mid-1 mid mid+1 right + */ public class Quick { public int[] quickSort(int[] nums) { return mainSort(nums, 0, nums.length - 1); } + // 递归方法 private int[] mainSort(int[] nums, int left, int right) { - if (left < right) { - int mid = partition(nums, left, right); - // 递归排序左右两部分 - mainSort(nums, left, mid - 1); - mainSort(nums, mid + 1, right); + if (left >= right) { + return nums; } + int mid = partition(nums, left, right); + mainSort(nums, left, mid - 1); + mainSort(nums, mid + 1, right); return nums; } @@ -29,6 +64,7 @@ private int partition(int[] nums, int left, int right) { return index - 1; } + // 交换元素 private void swap(int[] nums, int x, int y) { int temp = nums[x]; nums[x] = nums[y]; @@ -39,7 +75,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Quick quick = new Quick(); nums = quick.quickSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Radix.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Radix.java" index a631cea..495207b 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Radix.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Radix.java" @@ -3,29 +3,31 @@ import java.util.ArrayList; import java.util.Arrays; -// 基数排序 +/* +基数排序: +1、创建0-9共10个桶 +2、获取最大数字的长度作为排序次数 +3、遍历数字,每个数字从低位到高位,获取数字的基数,由基数获取对应的桶,并将数字放入对应的桶中 +4、遍历10个桶,有序地将每个桶的数字放回原数组,然后清空桶,准备下一轮排序 +5、在低位有序的前提下,对高位排序,最终得到整体排序数组 + */ public class Radix { public int[] radixSort(int[] nums) { - // 创建0-9共10个桶 - ArrayList> bucket = new ArrayList<>(); - for (int i = 0; i < 10; i++) - bucket.add(new ArrayList<>()); - // 获取最大数字的长度作为排序次数 + ArrayList> buckets = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + buckets.add(new ArrayList<>()); + } int times = String.valueOf(Arrays.stream(nums).max().getAsInt()).length(); for (int i = 0; i < times; i++) { - // 从低位到高位,获取数字的基数,并将数字放入对应的桶中 - for (int num : nums) - bucket.get(num / (int) Math.pow(10, i) % 10).add(num); - // 有序地将每个桶的数字放回原数组 - int k = 0; - // 遍历10个桶 - for (int m = 0; m < 10; m++) { - ArrayList list = bucket.get(m); - // 遍历桶中所有数字 - for (int n = 0; n < list.size(); n++) - nums[k++] = (int) list.get(n); - // 清空桶 - list.clear(); + for (int num : nums) { + buckets.get(num / (int) Math.pow(10, i) % 10).add(num); + } + int index = 0; + for (ArrayList bucket : buckets) { + for (Integer num : bucket) { + nums[index++] = num; + } + bucket.clear(); } } return nums; @@ -35,7 +37,8 @@ public static void main(String[] args) { int[] nums = {10, 244, 6, 212, 38, 528, 7777, 555, 9}; Radix radix = new Radix(); nums = radix.radixSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Select.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Select.java" index e56ba52..f1b4b16 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Select.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Select.java" @@ -1,18 +1,21 @@ package sort; -// 选择排序 +/* +选择排序:第一个for循环遍历待排序位置,从左到右依次排序。第二个for循环从左到右遍历查找最小元素的索引,然后与待排序位置交换 + */ public class Select { public int[] selectSort(int[] nums) { int n = nums.length; for (int i = 0; i < n - 1; i++) { - int min_index = i; + int minIndex = i; for (int j = i + 1; j < n; j++) { - if (nums[j] < nums[min_index]) - min_index = j; + if (nums[j] < nums[minIndex]) { + minIndex = j; + } } int temp = nums[i]; - nums[i] = nums[min_index]; - nums[min_index] = temp; + nums[i] = nums[minIndex]; + nums[minIndex] = temp; } return nums; } @@ -21,7 +24,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Select select = new Select(); nums = select.selectSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Shell.java" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Shell.java" index a428752..d1afd7d 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Shell.java" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Java/Shell.java" @@ -1,22 +1,29 @@ package sort; -// 希尔排序 +/* +希尔排序:分组插入排序 +1、第一个for循环表示每组间隔,间隔越小则分组内元素越多,不断减小间隔,循环直到间隔为1,整体归为一组 +2、第二个和第三个for循环表示对每个分组进行插入排序 + 第二个for循环从左到右遍历要排序的元素,元素分别属于不同的分组 + 第三个for循环从右到左将要排序的元素进行交换排序,通过gap获取对应分组内的元素进行交换 +3、i从gap开始,j从i开始,条件j>=gap保证j-gap不会越界 +4、元素比较结果不用交换时,左边元素已经排序,可结束本轮排序 + */ public class Shell { public int[] shellSort(int[] nums) { int n = nums.length; - int gap = n / 2; - // 分组插入排序 - while (gap > 0) { + for (int gap = n / 2; gap > 0; gap /= 2) { for (int i = gap; i < n; i++) { - for (int j = i - gap; j >= 0; j -= gap) { - if (nums[j] > nums[j + gap]) { + for (int j = i; j >= gap; j -= gap) { + if (nums[j] < nums[j - gap]) { int temp = nums[j]; - nums[j] = nums[j + gap]; - nums[j + gap] = temp; + nums[j] = nums[j - gap]; + nums[j - gap] = temp; + } else { + break; } } } - gap /= 2; } return nums; } @@ -25,7 +32,8 @@ public static void main(String[] args) { int[] nums = {1, 4, 6, 2, 3, 8, 7, 5, 9}; Shell shell = new Shell(); nums = shell.shellSort(nums); - for (int num : nums) + for (int num : nums) { System.out.println(num); + } } } diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/01.\345\206\222\346\263\241\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/01.\345\206\222\346\263\241\346\216\222\345\272\217.py" similarity index 97% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/01.\345\206\222\346\263\241\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/01.\345\206\222\346\263\241\346\216\222\345\272\217.py" index 78eba9b..2769c8f 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/01.\345\206\222\346\263\241\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/01.\345\206\222\346\263\241\346\216\222\345\272\217.py" @@ -1,13 +1,13 @@ -# 外循环控制循环次数,内循环控制左右元素两两比较,若第一个大于第二个则交换位置,最终最大的元素会放在最右边 -# 除去最后一个元素,对剩余元素重复以上循环 -def bubble_sort(nums): - for i in range(1, len(nums)): - for j in range(len(nums)-i): - if nums[j] > nums[j+1]: - nums[j], nums[j+1] = nums[j+1], nums[j] - return nums - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] - print(bubble_sort(nums)) +# 外循环控制循环次数,内循环控制左右元素两两比较,若第一个大于第二个则交换位置,最终最大的元素会放在最右边 +# 除去最后一个元素,对剩余元素重复以上循环 +def bubble_sort(nums): + for i in range(1, len(nums)): + for j in range(len(nums)-i): + if nums[j] > nums[j+1]: + nums[j], nums[j+1] = nums[j+1], nums[j] + return nums + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] + print(bubble_sort(nums)) diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/02.\351\200\211\346\213\251\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/02.\351\200\211\346\213\251\346\216\222\345\272\217.py" similarity index 97% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/02.\351\200\211\346\213\251\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/02.\351\200\211\346\213\251\346\216\222\345\272\217.py" index 22320ac..9b5faba 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/02.\351\200\211\346\213\251\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/02.\351\200\211\346\213\251\346\216\222\345\272\217.py" @@ -1,15 +1,15 @@ -# 外循环控制循环次数,内循环查找出最小元素,并与第一个元素交换位置 -# 除去第一个元素,对剩余元素重复以上循环 -def select_sort(nums): - for i in range(len(nums)-1): - min_index = i - for j in range(i+1, len(nums)): - if nums[j] < nums[min_index]: - min_index = j - nums[min_index], nums[i] = nums[i], nums[min_index] - return nums - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] +# 外循环控制循环次数,内循环查找出最小元素,并与第一个元素交换位置 +# 除去第一个元素,对剩余元素重复以上循环 +def select_sort(nums): + for i in range(len(nums)-1): + min_index = i + for j in range(i+1, len(nums)): + if nums[j] < nums[min_index]: + min_index = j + nums[min_index], nums[i] = nums[i], nums[min_index] + return nums + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] print(select_sort(nums)) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/03.\346\217\222\345\205\245\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/03.\346\217\222\345\205\245\346\216\222\345\272\217.py" similarity index 97% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/03.\346\217\222\345\205\245\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/03.\346\217\222\345\205\245\346\216\222\345\272\217.py" index 00bde69..0b907e9 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/03.\346\217\222\345\205\245\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/03.\346\217\222\345\205\245\346\216\222\345\272\217.py" @@ -1,15 +1,15 @@ -# 从左往右遍历每个元素,将遍历到的元素插入到该元素左边序列中,且位置在从右往左第一个小于等于该元素的元素右边 -def insert_sort(nums): - if len(nums) < 2: - return nums - for i in range(1, len(nums)): - j = i - while j > 0 and nums[j] < nums[j-1]: - nums[j], nums[j-1] = nums[j-1], nums[j] - j -= 1 - return nums - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] +# 从左往右遍历每个元素,将遍历到的元素插入到该元素左边序列中,且位置在从右往左第一个小于等于该元素的元素右边 +def insert_sort(nums): + if len(nums) < 2: + return nums + for i in range(1, len(nums)): + j = i + while j > 0 and nums[j] < nums[j-1]: + nums[j], nums[j-1] = nums[j-1], nums[j] + j -= 1 + return nums + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] print(insert_sort(nums)) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/04.\345\270\214\345\260\224\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/04.\345\270\214\345\260\224\346\216\222\345\272\217.py" similarity index 96% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/04.\345\270\214\345\260\224\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/04.\345\270\214\345\260\224\346\216\222\345\272\217.py" index 2359622..b84f9de 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/04.\345\270\214\345\260\224\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/04.\345\270\214\345\260\224\346\216\222\345\272\217.py" @@ -1,16 +1,16 @@ -# 把元素按下标的一定增量分组,对每组使用直接插入排序算法排序 -def shell_sort(nums): - n = len(nums) - gap = n // 2 - while gap > 0: - for i in range(gap, n): - while i >= gap and nums[i] < nums[i-gap]: - nums[i], nums[i-gap] = nums[i-gap], nums[i] - i -= gap - gap //= 2 - return nums - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] +# 把元素按下标的一定增量分组,对每组使用直接插入排序算法排序 +def shell_sort(nums): + n = len(nums) + gap = n // 2 + while gap > 0: + for i in range(gap, n): + while i >= gap and nums[i] < nums[i-gap]: + nums[i], nums[i-gap] = nums[i-gap], nums[i] + i -= gap + gap //= 2 + return nums + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] print(shell_sort(nums)) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/05.\345\275\222\345\271\266\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/05.\345\275\222\345\271\266\346\216\222\345\272\217.py" similarity index 96% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/05.\345\275\222\345\271\266\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/05.\345\275\222\345\271\266\346\216\222\345\272\217.py" index b57be00..78a7a44 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/05.\345\275\222\345\271\266\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/05.\345\275\222\345\271\266\346\216\222\345\272\217.py" @@ -1,28 +1,28 @@ -# 将数组分解最小,然后依次合并两个有序数组 -# 合并思路:比较两个数组的最左边的数,取较小者,取了后相应的指针往右移一位。继续比较,直至一个数组为空,最后复制另一个数组的剩余部分 -def merge_sort(nums): - if len(nums) < 2: - return nums - left = merge_sort(nums[:len(nums)//2]) - right = merge_sort(nums[len(nums)//2:]) - return merge(left, right) - - -def merge(left, right): - l = r = 0 - res = [] - while l < len(left) and r < len(right): - if left[l] < right[r]: - res.append(left[l]) - l += 1 - else: - res.append(right[r]) - r += 1 - res += left[l:] - res += right[r:] - return res - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] +# 将数组分解最小,然后依次合并两个有序数组 +# 合并思路:比较两个数组的最左边的数,取较小者,取了后相应的指针往右移一位。继续比较,直至一个数组为空,最后复制另一个数组的剩余部分 +def merge_sort(nums): + if len(nums) < 2: + return nums + left = merge_sort(nums[:len(nums)//2]) + right = merge_sort(nums[len(nums)//2:]) + return merge(left, right) + + +def merge(left, right): + l = r = 0 + res = [] + while l < len(left) and r < len(right): + if left[l] < right[r]: + res.append(left[l]) + l += 1 + else: + res.append(right[r]) + r += 1 + res += left[l:] + res += right[r:] + return res + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] print(merge_sort(nums)) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/06.\345\277\253\351\200\237\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/06.\345\277\253\351\200\237\346\216\222\345\272\217.py" similarity index 96% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/06.\345\277\253\351\200\237\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/06.\345\277\253\351\200\237\346\216\222\345\272\217.py" index 8df12c9..d1b7b8e 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/06.\345\277\253\351\200\237\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/06.\345\277\253\351\200\237\346\216\222\345\272\217.py" @@ -1,74 +1,74 @@ -# 先在数组中挑出一个“基准”元素,比它小的放左边,比它大的放右边 - -# 递归,逐一赋值形式 -def quick_sort(nums): - l, r = 0, len(nums)-1 - # 数组为空或只有一个元素 - if l >= r: - return nums - key = nums[l] - while l < r: - while l < r and nums[r] >= key: - r -= 1 - nums[l] = nums[r] - while l < r and nums[l] <= key: - l += 1 - nums[r] = nums[l] - nums[l] = key - l_nums = quick_sort(nums[:l]) - r_nums = quick_sort(nums[l+1:]) - return l_nums + [key] + r_nums - - -# 递归,两者交换形式 -def quick_sort(nums): - l, r = 0, len(nums)-1 - if l >= r: - return nums - p = l - while l < r: - while l < r and nums[r] >= nums[p]: - r -= 1 - while l < r and nums[l] <= nums[p]: - l += 1 - nums[r], nums[l] = nums[l], nums[r] - nums[l], nums[p] = nums[p], nums[l] - l_nums = quick_sort(nums[:l]) - r_nums = quick_sort(nums[l+1:]) - return l_nums + [nums[l]] + r_nums - - -# 非递归,栈实现 -def quick_sort(nums): - if len(nums) < 2: - return nums - stack = [] - stack.append(0) - stack.append(len(nums)-1) - while stack: - l = stack.pop(0) - r = stack.pop(0) - index = partition(nums, l, r) - if l < index: - stack.append(l) - stack.append(index-1) - if r > index: - stack.append(index+1) - stack.append(r) - return nums - -def partition(nums, l, r): - p = l - while l < r: - while l < r and nums[r] >= nums[p]: - r -= 1 - while l < r and nums[l] < nums[p]: - l += 1 - nums[l], nums[r] = nums[r], nums[l] - nums[p], nums[l] = nums[l], nums[p] - return l - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] - print(quick_sort(nums)) +# 先在数组中挑出一个“基准”元素,比它小的放左边,比它大的放右边 + +# 递归,逐一赋值形式 +def quick_sort(nums): + l, r = 0, len(nums)-1 + # 数组为空或只有一个元素 + if l >= r: + return nums + key = nums[l] + while l < r: + while l < r and nums[r] >= key: + r -= 1 + nums[l] = nums[r] + while l < r and nums[l] <= key: + l += 1 + nums[r] = nums[l] + nums[l] = key + l_nums = quick_sort(nums[:l]) + r_nums = quick_sort(nums[l+1:]) + return l_nums + [key] + r_nums + + +# 递归,两者交换形式 +def quick_sort(nums): + l, r = 0, len(nums)-1 + if l >= r: + return nums + p = l + while l < r: + while l < r and nums[r] >= nums[p]: + r -= 1 + while l < r and nums[l] <= nums[p]: + l += 1 + nums[r], nums[l] = nums[l], nums[r] + nums[l], nums[p] = nums[p], nums[l] + l_nums = quick_sort(nums[:l]) + r_nums = quick_sort(nums[l+1:]) + return l_nums + [nums[l]] + r_nums + + +# 非递归,栈实现 +def quick_sort(nums): + if len(nums) < 2: + return nums + stack = [] + stack.append(0) + stack.append(len(nums)-1) + while stack: + l = stack.pop(0) + r = stack.pop(0) + index = partition(nums, l, r) + if l < index: + stack.append(l) + stack.append(index-1) + if r > index: + stack.append(index+1) + stack.append(r) + return nums + +def partition(nums, l, r): + p = l + while l < r: + while l < r and nums[r] >= nums[p]: + r -= 1 + while l < r and nums[l] < nums[p]: + l += 1 + nums[l], nums[r] = nums[r], nums[l] + nums[p], nums[l] = nums[l], nums[p] + return l + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] + print(quick_sort(nums)) diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/07.\345\240\206\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/07.\345\240\206\346\216\222\345\272\217.py" similarity index 96% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/07.\345\240\206\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/07.\345\240\206\346\216\222\345\272\217.py" index 3977c4f..6584319 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/07.\345\240\206\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/07.\345\240\206\346\216\222\345\272\217.py" @@ -1,56 +1,56 @@ -def heap_sort(nums): - n = len(nums) - # 最后一个有子节点的结点的索引 - first = n//2-1 - # 构造最大堆。逐个有子节点的结点进行调整 - for start in range(first, -1, -1): - max_heapify(nums, start, n-1) - # 将最大堆转化成有序数组 - for end in range(n-1, 0, -1): - # 最后一个元素与第一个交换位置 - nums[end], nums[0] = nums[0], nums[end] - # 交换后排除最后一个元素,重新调整成最大堆 - max_heapify(nums, 0, end-1) - return nums - - -# 最大堆调整。子节点较大者与父节点交换 -def max_heapify(nums, start, end): - root = start - # 父节点交换下来后判新子节点是否还可继续交换 - while True: - child = 2*root+1 - if child > end: - break - # 获取较大子节点 - if child+1 <= end and nums[child] < nums[child+1]: - child += 1 - # 较大子节点成为父节点 - if nums[child] > nums[root]: - nums[child], nums[root] = nums[root], nums[child] - root = child - else: - break - - -# 最小堆调整。子节点较小者与父节点交换 -def min_heapify(nums, start, end): - root = start - while True: - child = 2*root+1 - if child > end: - break - # 获取较小子节点 - if child+1 <= end and nums[child] > nums[child+1]: - child += 1 - # 较小子节点成为父节点 - if nums[child] < nums[root]: - nums[child], nums[root] = nums[root], nums[child] - root = child - else: - break - - -if __name__ == '__main__': - nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] - print(heap_sort(nums)) +def heap_sort(nums): + n = len(nums) + # 最后一个有子节点的结点的索引 + first = n//2-1 + # 构造最大堆。逐个有子节点的结点进行调整 + for start in range(first, -1, -1): + max_heapify(nums, start, n-1) + # 将最大堆转化成有序数组 + for end in range(n-1, 0, -1): + # 最后一个元素与第一个交换位置 + nums[end], nums[0] = nums[0], nums[end] + # 交换后排除最后一个元素,重新调整成最大堆 + max_heapify(nums, 0, end-1) + return nums + + +# 最大堆调整。子节点较大者与父节点交换 +def max_heapify(nums, start, end): + root = start + # 父节点交换下来后判新子节点是否还可继续交换 + while True: + child = 2*root+1 + if child > end: + break + # 获取较大子节点 + if child+1 <= end and nums[child] < nums[child+1]: + child += 1 + # 较大子节点成为父节点 + if nums[child] > nums[root]: + nums[child], nums[root] = nums[root], nums[child] + root = child + else: + break + + +# 最小堆调整。子节点较小者与父节点交换 +def min_heapify(nums, start, end): + root = start + while True: + child = 2*root+1 + if child > end: + break + # 获取较小子节点 + if child+1 <= end and nums[child] > nums[child+1]: + child += 1 + # 较小子节点成为父节点 + if nums[child] < nums[root]: + nums[child], nums[root] = nums[root], nums[child] + root = child + else: + break + + +if __name__ == '__main__': + nums = [2, 1, 6, 7, 9, 5, 0, 4, 3, 8] + print(heap_sort(nums)) diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/08.\350\256\241\346\225\260\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/08.\350\256\241\346\225\260\346\216\222\345\272\217.py" similarity index 97% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/08.\350\256\241\346\225\260\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/08.\350\256\241\346\225\260\346\216\222\345\272\217.py" index 4f9285e..92fe74c 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/08.\350\256\241\346\225\260\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/08.\350\256\241\346\225\260\346\216\222\345\272\217.py" @@ -1,20 +1,20 @@ -def count_sort(nums): - max_num, min_num = max(nums), min(nums) - count = [0] * (max_num - min_num + 1) - res = [0] * len(nums) - # 记录每个元素出现次数 - for num in nums: - count[num-min_num] += 1 - # 加上前一元素值,此时每个元素的含义是包括当前元素在内有多少个元素在桶里 - for i in range(1, len(count)): - count[i] += count[i-1] - # 获取每个元素在最终数组中对应位置索引并存入 - for num in nums: - res[count[num-min_num]-1] = num - count[num-min_num] -= 1 - return res - - -if __name__ == '__main__': - nums = [2, 1, 8, 9, 9, 5, 9, 4, 4, 8] +def count_sort(nums): + max_num, min_num = max(nums), min(nums) + count = [0] * (max_num - min_num + 1) + res = [0] * len(nums) + # 记录每个元素出现次数 + for num in nums: + count[num-min_num] += 1 + # 加上前一元素值,此时每个元素的含义是包括当前元素在内有多少个元素在桶里 + for i in range(1, len(count)): + count[i] += count[i-1] + # 获取每个元素在最终数组中对应位置索引并存入 + for num in nums: + res[count[num-min_num]-1] = num + count[num-min_num] -= 1 + return res + + +if __name__ == '__main__': + nums = [2, 1, 8, 9, 9, 5, 9, 4, 4, 8] print(count_sort(nums)) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/09.\346\241\266\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/09.\346\241\266\346\216\222\345\272\217.py" similarity index 97% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/09.\346\241\266\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/09.\346\241\266\346\216\222\345\272\217.py" index c86fec8..e8338e7 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/09.\346\241\266\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/09.\346\241\266\346\216\222\345\272\217.py" @@ -1,16 +1,16 @@ -# 获取数组最大值和最小值并构建在该范围的数组长度,数组记录元素出现的个数,最后遍历数组获取对应个数的元素 -def bucket_sort(nums): - max_num, min_num = max(nums), min(nums) - count = [0 for _ in range(min_num, max_num+1)] - res = [] - for num in nums: - count[num-min_num] += 1 - for index in range(len(count)): - if count[index] != 0: - res += [index+min_num] * count[index] - return res - - -if __name__ == '__main__': - nums = [2, 1, 8, 9, 9, 5, 9, 4, 4, 8] +# 获取数组最大值和最小值并构建在该范围的数组长度,数组记录元素出现的个数,最后遍历数组获取对应个数的元素 +def bucket_sort(nums): + max_num, min_num = max(nums), min(nums) + count = [0 for _ in range(min_num, max_num+1)] + res = [] + for num in nums: + count[num-min_num] += 1 + for index in range(len(count)): + if count[index] != 0: + res += [index+min_num] * count[index] + return res + + +if __name__ == '__main__': + nums = [2, 1, 8, 9, 9, 5, 9, 4, 4, 8] print(bucket_sort(nums)) \ No newline at end of file diff --git "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/10.\345\237\272\346\225\260\346\216\222\345\272\217.py" "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/10.\345\237\272\346\225\260\346\216\222\345\272\217.py" similarity index 97% rename from "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/10.\345\237\272\346\225\260\346\216\222\345\272\217.py" rename to "\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/10.\345\237\272\346\225\260\346\216\222\345\272\217.py" index 9852f80..2656dbd 100644 --- "a/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225/10.\345\237\272\346\225\260\346\216\222\345\272\217.py" +++ "b/\345\215\201\345\244\247\346\216\222\345\272\217\347\256\227\346\263\225_Python/10.\345\237\272\346\225\260\346\216\222\345\272\217.py" @@ -1,15 +1,15 @@ -def radix_sort(nums): - # 最大数字长度作为排序次数 - for k in range(len(str(max(nums)))): - # 数字0-9建立10个桶 - buckets = [[] for _ in range(10)] - # 对每个元素从低位到高位获取对应数字,放入对应的桶 - for num in nums: - buckets[num//(10**k) % 10].append(num) - nums = [num for bucket in buckets for num in bucket] - return nums - - -if __name__ == '__main__': - nums = [21, 111, 84, 91, 454, 52, 312, 421, 4, 8] +def radix_sort(nums): + # 最大数字长度作为排序次数 + for k in range(len(str(max(nums)))): + # 数字0-9建立10个桶 + buckets = [[] for _ in range(10)] + # 对每个元素从低位到高位获取对应数字,放入对应的桶 + for num in nums: + buckets[num//(10**k) % 10].append(num) + nums = [num for bucket in buckets for num in bucket] + return nums + + +if __name__ == '__main__': + nums = [21, 111, 84, 91, 454, 52, 312, 421, 4, 8] print(radix_sort(nums)) \ No newline at end of file diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution002.java" "b/\347\203\255\351\242\230HOT100_Java/Solution002.java" deleted file mode 100644 index 81714a7..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution002.java" +++ /dev/null @@ -1,35 +0,0 @@ -package HOT100; - - -/* -class ListNode { - int val; - ListNode next; - ListNode(int x) { val = x; } -} -*/ - - -// 两数相加 -public class Solution002 { - public ListNode addTwoNumbers(ListNode l1, ListNode l2) { - ListNode root = new ListNode(0); - ListNode cursor = root; - int carry = 0; - - while (l1 != null || l2 != null || carry != 0) { - int l1Val = l1 != null ? l1.val : 0; - int l2Val = l2 != null ? l2.val : 0; - int sumVal = l1Val + l2Val + carry; - carry = sumVal / 10; - - ListNode sumNode = new ListNode(sumVal % 10); - cursor.next = sumNode; - cursor = sumNode; - - if (l1 != null) l1 = l1.next; - if (l2 != null) l2 = l2.next; - } - return root.next; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution003.java" "b/\347\203\255\351\242\230HOT100_Java/Solution003.java" deleted file mode 100644 index 367b0d8..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution003.java" +++ /dev/null @@ -1,23 +0,0 @@ -package HOT100; - -import java.util.HashMap; - -// 无重复字符的最长子串 -public class Solution003 { - public int lengthOfLongestSubstring(String s) { - HashMap map = new HashMap<>(); - int start = 0, res = 0; - - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - // 如果字符重复,则更新起点 - if (map.containsKey(c)) - start = Math.max(start, map.get(c) + 1); - // 更新当前字符索引 - map.put(c, i); - // 计算当前最长子串 - res = Math.max(res, i - start + 1); - } - return res; - } -} \ No newline at end of file diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution004.java" "b/\347\203\255\351\242\230HOT100_Java/Solution004.java" deleted file mode 100644 index be14bd0..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution004.java" +++ /dev/null @@ -1,19 +0,0 @@ -package HOT100; - -import java.util.Arrays; - -// 寻找两个有序数组的中位数 -public class Solution004 { - public double findMedianSortedArrays(int[] nums1, int[] nums2) { - // Arrays.copyOf(源数组, 复制长度) - int[] nums = Arrays.copyOf(nums1, nums1.length + nums2.length); - // System.arraycopy(源数组, 源数组起始索引, 目标数组, 目标数组起始索引, 复制长度) - System.arraycopy(nums2, 0, nums, nums1.length, nums2.length); - Arrays.sort(nums); - - if (nums.length % 2 == 0) - return ((float) nums[nums.length / 2 - 1] + nums[nums.length / 2]) / 2; - else - return (float) nums[nums.length / 2]; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution011.java" "b/\347\203\255\351\242\230HOT100_Java/Solution011.java" deleted file mode 100644 index 1ffcc06..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution011.java" +++ /dev/null @@ -1,18 +0,0 @@ -package HOT100; - -// 盛最多水的容器 -public class Solution011 { - public int maxArea(int[] height) { - int l = 0, r = height.length - 1, res = 0; - while (l < r) { - if (height[l] <= height[r]) { - res = Math.max(res, height[l] * (r - l)); - l++; - } else { - res = Math.max(res, height[r] * (r - l)); - r--; - } - } - return res; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution015.java" "b/\347\203\255\351\242\230HOT100_Java/Solution015.java" deleted file mode 100644 index 79511b4..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution015.java" +++ /dev/null @@ -1,28 +0,0 @@ -package HOT100; - -import java.util.*; - -// 三数之和 -public class Solution015 { - public List> threeSum(int[] nums) { - Set> set = new HashSet<>(); - Arrays.sort(nums); - int n = nums.length; - - for (int i = 0; i < n - 2; i++) { - int l = i + 1, r = n - 1; - while (l < r) { - if (nums[l] + nums[r] + nums[i] == 0) { - set.add(Arrays.asList(nums[l], nums[r], nums[i])); - l++; - r--; - } else if (nums[l] + nums[r] + nums[i] < 0) { - l++; - } else { - r--; - } - } - } - return new ArrayList<>(set); - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution017.java" "b/\347\203\255\351\242\230HOT100_Java/Solution017.java" deleted file mode 100644 index f213256..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution017.java" +++ /dev/null @@ -1,38 +0,0 @@ -package HOT100; - -import java.util.*; - -// 电话号码的字母组合 -public class Solution017 { - List list = new ArrayList<>(); - Map map = new HashMap() { - { - put("2", "abc"); - put("3", "def"); - put("4", "ghi"); - put("5", "jkl"); - put("6", "mno"); - put("7", "pqrs"); - put("8", "tuv"); - put("9", "wxyz"); - } - }; - - public List letterCombinations(String digits) { - if (digits.length() != 0) - combine("", digits); - return list; - } - - private void combine(String res, String digits) { - if (digits.length() == 0) { - list.add(res); - } else { - String str = map.get(digits.charAt(0) + ""); - for (int i = 0; i < str.length(); i++) { - combine(res + str.charAt(i), digits.substring(1)); - } - } - } - -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution200.java" "b/\347\203\255\351\242\230HOT100_Java/Solution200.java" deleted file mode 100644 index 37d85db..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution200.java" +++ /dev/null @@ -1,31 +0,0 @@ -package HOT100; - -// 岛屿数量 -public class Solution200 { - public int numIslands(char[][] grid) { - if (grid.length == 0) - return 0; - - int m = grid.length, n = grid[0].length, res = 0; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (grid[i][j] == '1') { - dfs(grid, i, j); - res++; - } - } - } - return res; - } - - private void dfs(char[][] grid, int i, int j) { - if (i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && grid[i][j] == '1') { - grid[i][j] = 0; - dfs(grid, i + 1, j); - dfs(grid, i - 1, j); - dfs(grid, i, j + 1); - dfs(grid, i, j - 1); - } - } - -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution236.java" "b/\347\203\255\351\242\230HOT100_Java/Solution236.java" deleted file mode 100644 index 4a1591f..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution236.java" +++ /dev/null @@ -1,25 +0,0 @@ -package HOT100; - - -/* -class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } -} -*/ - - -// 二叉树的最近公共祖先 -public class Solution236 { - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - if (root == null || root == p || root == q) - return root; - TreeNode left = lowestCommonAncestor(root.left, p, q); - TreeNode right = lowestCommonAncestor(root.right, p, q); - if (left != null && right != null) - return root; - return left != null ? left : right; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution300.java" "b/\347\203\255\351\242\230HOT100_Java/Solution300.java" deleted file mode 100644 index 1ae8082..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution300.java" +++ /dev/null @@ -1,26 +0,0 @@ -package HOT100; - -import java.util.Arrays; - -// 最长上升子序列 -public class Solution300 { - public int lengthOfLIS(int[] nums) { - int n = nums.length; - if (n < 2) - return n; - - int[] dp = new int[n]; - Arrays.fill(dp, 1); - int res = 1; - - for (int i = 1; i < n; i++) { - for (int j = 0; j < i; j++) { - if (nums[i] > nums[j]) { - dp[i] = Math.max(dp[i], dp[j] + 1); - res = Math.max(res, dp[i]); - } - } - } - return res; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution437.java" "b/\347\203\255\351\242\230HOT100_Java/Solution437.java" deleted file mode 100644 index 2dae57e..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution437.java" +++ /dev/null @@ -1,32 +0,0 @@ -package HOT100; - - -/* -class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } -} -*/ - - -// 路径总和 -public class Solution437 { - public int pathSum(TreeNode root, int sum) { - if (root == null) - return 0; - return dfs(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); - } - - private int dfs(TreeNode root, int sum) { - int res = 0; - if (root == null) - return res; - if (root.val == sum) - res += 1; - res += dfs(root.left, sum - root.val); - res += dfs(root.right, sum - root.val); - return res; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution461.java" "b/\347\203\255\351\242\230HOT100_Java/Solution461.java" deleted file mode 100644 index 97136fb..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution461.java" +++ /dev/null @@ -1,15 +0,0 @@ -package HOT100; - - -// 汉明距离 -public class Solution461 { - public int hammingDistance(int x, int y) { - int num = x ^ y; - int res = 0; - while (num != 0) { - res += num & 1; - num >>= 1; - } - return res; - } -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution538.java" "b/\347\203\255\351\242\230HOT100_Java/Solution538.java" deleted file mode 100644 index 5e38869..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution538.java" +++ /dev/null @@ -1,28 +0,0 @@ -package HOT100; - - -/* -class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } -} -*/ - - -// 把二叉搜索树转换为累加树 -public class Solution538 { - int num = 0; - - public TreeNode convertBST(TreeNode root) { - if (root != null) { - convertBST(root.right); - root.val += num; - num = root.val; - convertBST(root.left); - } - return root; - } - -} diff --git "a/\347\203\255\351\242\230HOT100_Java/Solution617.java" "b/\347\203\255\351\242\230HOT100_Java/Solution617.java" deleted file mode 100644 index efe564a..0000000 --- "a/\347\203\255\351\242\230HOT100_Java/Solution617.java" +++ /dev/null @@ -1,27 +0,0 @@ -package HOT100; - - -/* -class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } -} -*/ - - -// 合并二叉树 -public class Solution617 { - public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { - if (t1 == null) - return t2; - if (t2 == null) - return t1; - return t1 != null ? t1 : t2; - TreeNode root = new TreeNode(t1.val + t2.val); - root.left = mergeTrees(t1.left, t2.left); - root.right = mergeTrees(t1.right, t2.right); - return root; - } -}