Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 58 additions & 43 deletions problems/0045.跳跃游戏II.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,66 +205,81 @@ class Solution {
```

### Python

贪心(版本一)
```python
class Solution:
def jump(self, nums: List[int]) -> int:
if len(nums) == 1: return 0
ans = 0
curDistance = 0
nextDistance = 0
def jump(self, nums):
if len(nums) == 1:
return 0

cur_distance = 0 # 当前覆盖最远距离下标
ans = 0 # 记录走的最大步数
next_distance = 0 # 下一步覆盖最远距离下标

for i in range(len(nums)):
nextDistance = max(i + nums[i], nextDistance)
if i == curDistance:
if curDistance != len(nums) - 1:
ans += 1
curDistance = nextDistance
if nextDistance >= len(nums) - 1: break
next_distance = max(nums[i] + i, next_distance) # 更新下一步覆盖最远距离下标
if i == cur_distance: # 遇到当前覆盖最远距离下标
ans += 1 # 需要走下一步
cur_distance = next_distance # 更新当前覆盖最远距离下标(相当于加油了)
if next_distance >= len(nums) - 1: # 当前覆盖最远距离达到数组末尾,不用再做ans++操作,直接结束
break

return ans

```
贪心(版本二)

```python
# 贪心版本二
class Solution:
def jump(self, nums: List[int]) -> int:
if len(nums) == 1:
return 0
curDistance, nextDistance = 0, 0
step = 0
for i in range(len(nums)-1):
nextDistance = max(nextDistance, nums[i]+i)
if i == curDistance:
curDistance = nextDistance
step += 1
return step
def jump(self, nums):
cur_distance = 0 # 当前覆盖的最远距离下标
ans = 0 # 记录走的最大步数
next_distance = 0 # 下一步覆盖的最远距离下标

for i in range(len(nums) - 1): # 注意这里是小于len(nums) - 1,这是关键所在
next_distance = max(nums[i] + i, next_distance) # 更新下一步覆盖的最远距离下标
if i == cur_distance: # 遇到当前覆盖的最远距离下标
cur_distance = next_distance # 更新当前覆盖的最远距离下标
ans += 1

return ans

```
贪心(版本三) 类似‘55-跳跃游戏’写法

```python
# 贪心版本三 - 类似‘55-跳跃游戏’写法
class Solution:
def jump(self, nums) -> int:
if len(nums)==1: return 0
i = 0
count = 0
cover = 0
while i<=cover:
for i in range(i,cover+1):
cover = max(nums[i]+i,cover)
if cover>=len(nums)-1: return count+1
count+=1
if len(nums)==1: # 如果数组只有一个元素,不需要跳跃,步数为0
return 0

```
i = 0 # 当前位置
count = 0 # 步数计数器
cover = 0 # 当前能够覆盖的最远距离

while i <= cover: # 当前位置小于等于当前能够覆盖的最远距离时循环
for i in range(i, cover+1): # 遍历从当前位置到当前能够覆盖的最远距离之间的所有位置
cover = max(nums[i]+i, cover) # 更新当前能够覆盖的最远距离
if cover >= len(nums)-1: # 如果当前能够覆盖的最远距离达到或超过数组的最后一个位置,直接返回步数+1
return count+1
count += 1 # 每一轮遍历结束后,步数+1


```
动态规划
```python
# 动态规划做法
class Solution:
def jump(self, nums: List[int]) -> int:
result = [10**4+1]*len(nums)
result[0]=0
for i in range(len(nums)):
for j in range(nums[i]+1):
if i+j<len(nums): result[i+j]=min(result[i+j],result[i]+1)
#print(result) #打印数组
return result[-1]
result = [10**4+1] * len(nums) # 初始化结果数组,初始值为一个较大的数
result[0] = 0 # 起始位置的步数为0

for i in range(len(nums)): # 遍历数组
for j in range(nums[i] + 1): # 在当前位置能够跳跃的范围内遍历
if i + j < len(nums): # 确保下一跳的位置不超过数组范围
result[i + j] = min(result[i + j], result[i] + 1) # 更新到达下一跳位置的最小步数

return result[-1] # 返回到达最后一个位置的最小步数


```

Expand Down
24 changes: 19 additions & 5 deletions problems/0053.最大子序和.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,35 @@ class Solution {
```

### Python
暴力法
```python
class Solution:
def maxSubArray(self, nums):
result = float('-inf') # 初始化结果为负无穷大
count = 0
for i in range(len(nums)): # 设置起始位置
count = 0
for j in range(i, len(nums)): # 从起始位置i开始遍历寻找最大值
count += nums[j]
result = max(count, result) # 更新最大值
return result

```
```python
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
result = -float('inf')
def maxSubArray(self, nums):
result = float('-inf') # 初始化结果为负无穷大
count = 0
for i in range(len(nums)):
count += nums[i]
if count > result:
if count > result: # 取区间累计的最大值(相当于不断确定最大子序终止位置)
result = count
if count <= 0:
if count <= 0: # 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
count = 0
return result
```


```
### Go

```go
Expand Down
22 changes: 14 additions & 8 deletions problems/0056.合并区间.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,24 @@ class Solution {
### Python
```python
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
if len(intervals) == 0: return intervals
intervals.sort(key=lambda x: x[0])
def merge(self, intervals):
result = []
result.append(intervals[0])
if len(intervals) == 0:
return result # 区间集合为空直接返回

intervals.sort(key=lambda x: x[0]) # 按照区间的左边界进行排序

result.append(intervals[0]) # 第一个区间可以直接放入结果集中

for i in range(1, len(intervals)):
last = result[-1]
if last[1] >= intervals[i][0]:
result[-1] = [last[0], max(last[1], intervals[i][1])]
if result[-1][1] >= intervals[i][0]: # 发现重叠区间
# 合并区间,只需要更新结果集最后一个区间的右边界,因为根据排序,左边界已经是最小的
result[-1][1] = max(result[-1][1], intervals[i][1])
else:
result.append(intervals[i])
result.append(intervals[i]) # 区间不重叠

return result

```

### Go
Expand Down
76 changes: 53 additions & 23 deletions problems/0134.加油站.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,44 +249,74 @@ class Solution {
```

### Python
暴力法
```python

class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
for i in range(len(cost)):
rest = gas[i] - cost[i] # 记录剩余油量
index = (i + 1) % len(cost) # 下一个加油站的索引

while rest > 0 and index != i: # 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了)
rest += gas[index] - cost[index] # 更新剩余油量
index = (index + 1) % len(cost) # 更新下一个加油站的索引

if rest >= 0 and index == i: # 如果以i为起点跑一圈,剩余油量>=0,并且回到起始位置
return i # 返回起始位置i

return -1 # 所有起始位置都无法环绕一圈,返回-1

```
贪心(版本一)
```python
# 解法1
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
n = len(gas)
cur_sum = 0
min_sum = float('inf')
curSum = 0 # 当前累计的剩余油量
minFuel = float('inf') # 从起点出发,油箱里的油量最小值

for i in range(n):
cur_sum += gas[i] - cost[i]
min_sum = min(min_sum, cur_sum)
for i in range(len(gas)):
rest = gas[i] - cost[i]
curSum += rest
if curSum < minFuel:
minFuel = curSum

if cur_sum < 0: return -1
if min_sum >= 0: return 0
if curSum < 0:
return -1 # 情况1:整个行程的总消耗大于总供给,无法完成一圈

for j in range(n - 1, 0, -1):
min_sum += gas[j] - cost[j]
if min_sum >= 0:
return j
if minFuel >= 0:
return 0 # 情况2:从起点出发到任何一个加油站时油箱的剩余油量都不会小于0,可以从起点出发完成一圈

return -1
```
for i in range(len(gas) - 1, -1, -1):
rest = gas[i] - cost[i]
minFuel += rest
if minFuel >= 0:
return i # 情况3:找到一个位置使得从该位置出发油箱的剩余油量不会小于0,返回该位置的索引

return -1 # 无法完成一圈

```
贪心(版本二)
```python
# 解法2
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
start = 0
curSum = 0
totalSum = 0
curSum = 0 # 当前累计的剩余油量
totalSum = 0 # 总剩余油量
start = 0 # 起始位置

for i in range(len(gas)):
curSum += gas[i] - cost[i]
totalSum += gas[i] - cost[i]
if curSum < 0:
curSum = 0
start = i + 1
if totalSum < 0: return -1

if curSum < 0: # 当前累计剩余油量curSum小于0
start = i + 1 # 起始位置更新为i+1
curSum = 0 # curSum重新从0开始累计

if totalSum < 0:
return -1 # 总剩余油量totalSum小于0,说明无法环绕一圈
return start


```

### Go
Expand Down
16 changes: 12 additions & 4 deletions problems/0135.分发糖果.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,21 @@ class Solution {
class Solution:
def candy(self, ratings: List[int]) -> int:
candyVec = [1] * len(ratings)

# 从前向后遍历,处理右侧比左侧评分高的情况
for i in range(1, len(ratings)):
if ratings[i] > ratings[i - 1]:
candyVec[i] = candyVec[i - 1] + 1
for j in range(len(ratings) - 2, -1, -1):
if ratings[j] > ratings[j + 1]:
candyVec[j] = max(candyVec[j], candyVec[j + 1] + 1)
return sum(candyVec)

# 从后向前遍历,处理左侧比右侧评分高的情况
for i in range(len(ratings) - 2, -1, -1):
if ratings[i] > ratings[i + 1]:
candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1)

# 统计结果
result = sum(candyVec)
return result

```

### Go
Expand Down
2 changes: 1 addition & 1 deletion problems/0225.用队列实现栈.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ class MyStack {

```
优化,使用一个 Queue 实现,但用卡哥的逻辑实现
```
```Java
class MyStack {
Queue<Integer> queue;

Expand Down
6 changes: 3 additions & 3 deletions problems/0406.根据身高重建队列.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ class Solution {
public int[][] reconstructQueue(int[][] people) {
// 身高从大到小排(身高相同k小的站前面)
Arrays.sort(people, (a, b) -> {
if (a[0] == b[0]) return a[1] - b[1];
return b[0] - a[0];
if (a[0] == b[0]) return a[1] - b[1]; // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
return b[0] - a[0]; //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
});

LinkedList<int[]> que = new LinkedList<>();

for (int[] p : people) {
que.add(p[1],p);
que.add(p[1],p); //Linkedlist.add(index, value),會將value插入到指定index裡。
}

return que.toArray(new int[people.length][]);
Expand Down
Loading