目录
旅行终点站
给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] = [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。
题目数据保证线路图会形成一条不存在循环的线路,因此只会有一个旅行终点站。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/destination-city
示例
输入:paths = [[“London”,“New York”],[“New York”,“Lima”],[“Lima”,“Sao Paulo”]]
输出:“Sao Paulo”
解释:从 “London” 出发,最后抵达终点站 “Sao Paulo” 。本次旅行的路线是 “London” -> “New York” -> “Lima” -> “Sao Paulo”
我的思路
出发站和终点站各做成一个列表。然后遍历终点站列表,不在出发站列表中的终点站即为所求。
我的代码
1
2
3
4
5
6
7
8
9
|
class Solution:
def destCity(self, paths) -> str:
starts = [path[0] for path in paths]
ends = [path[1] for path in paths]
res = ""
for end in ends:
if end not in starts:
res += end
return res
|
是否所有1都至少相隔k个元素
给你一个由若干 0 和 1 组成的数组 nums 以及整数 k。如果所有 1 都至少相隔 k 个元素,则返回 True ;否则,返回 False 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-all-1s-are-at-least-length-k-places-away
示例
输入:nums = [1,0,0,0,1,0,0,1], k = 2
输出:true
解释:每个 1 都至少相隔 2 个元素。
我的思路
遍历一次nums,先找第一个1,然后用计数器cnt记录每个1之间的间隔,若遍历过程中有cnt小于k的情况,则返回False,否则返回True
我的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Solution:
def kLengthApart(self, nums, k) -> bool:
cnt = 0
flag = False # 先找第一个1
for num in nums:
if flag:
if num == 1:
if cnt < k:
return False
cnt = 0
else:
cnt += 1
else:
if num == 1:
flag = True
return True
|
绝对值不超过限制的最长连续子数组
给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
如果不存在满足条件的子数组,则返回 0 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit
示例
输入:nums = [10,1,2,4,7,2], limit = 5
输出:4
解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5
别人的思路1
想到了单调栈,但是没想到要维护两个。
本题思路是单调栈+双指针。
遍历nums,维护两个单调栈,一个是单调升序栈asc,维护最左边是栈内最小值,一个是单调递减栈dsc,维护最左边是栈内最大值。
栈内元素不仅是元素值,也维护元素值在nums内的索引位置,最左边的元素的索引位置也需维护为栈内元素索引中最左的索引。
for循环里的前两个while实现了上面两个维护。最后一个while循环则维护满足绝对值不超过limit的合法左右指针,合法子数组的长度即右指针和左指针的差值加1。
别人的代码1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class Solution:
def longestSubarray(self, nums, limit):
asc = [] # 单调升序栈
dsc = [] # 单调递减栈
res = 0
left = 0 # 记录栈中元素在nums中最左边的索引
for right, num in enumerate(nums):
while asc and num < asc[-1][0]:
asc.pop()
asc.append((num, right))
while dsc and num > dsc[-1][0]:
dsc.pop()
dsc.append((num, right))
while dsc[0][0] - asc[0][0] > limit:
if left == asc[0][1]:
asc.pop(0)
if left == dsc[0][1]:
dsc.pop(0)
left += 1
res = max(res, right - left + 1)
return res
|
别人的思路2
利用Cpp里的 multiset 本身有序的特点来找最大绝对值差值
别人的代码2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int longestSubarray(vector<int>& nums, int limit) {
multiset<int> s;
int ans = 0;
int i = 0; // 记录s中在nums最左边的数的索引
for (int j = 0; j < nums.size(); j++) {
s.insert(nums[j]);
while (*s.rbegin() - *s.begin() > limit) {
s.erase(s.find(nums[i]));
i++;
}
ans = max(ans, j - i + 1);
}
return ans;
}
|
作者:ikaruga
链接:https://leetcode-cn.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/solution/longest-continuous-subarray-by-ikaruga/
有序矩阵中的第k个最小数组和
给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。
你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows
示例
输入:mat = [[1,3,11],[2,4,6]], k = 5
输出:7
解释:从每一行中选出一个元素,前 k 个和最小的数组分别是:
[1,2], [1,4], [3,2], [3,4], [1,6]。其中第 5 个的和是 7
别人的思路1
用preSum记录之前累加的和,因为矩阵每行是递增的,所以前k小的数必然是从每次前k小的和中累加得的,所以每次只需保留前k小的和作为剪枝。
按行遍历矩阵,遍历行内元素,这些元素加上preSum的值得到新的preSum。挺巧妙的遍历。
别人的代码1
1
2
3
4
5
6
7
8
9
10
|
class Solution:
def kthSmallest(self, mat: List[List[int]], k: int) -> int:
preSum = [0]
for row in mat:
tmp = []
for cur in row:
for pre in preSum:
tmp.append(cur + pre)
preSum = sorted(tmp)[:k]
return res[-1]
|
简化版:
1
2
3
4
5
6
|
class Solution:
def kthSmallest(self, mat: List[List[int]], k: int) -> int:
res = [0]
for row in mat:
res = sorted([cur + pre for cur in row for pre in res])[:k]
return res[-1]
|
别人的思路2
二分查找+DFS
别人的代码2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
class Solution {
public:
vector<vector<int>>temp;
int m,n;
int kthSmallest(vector<vector<int>>& mat, int k) {
temp=mat;
m=mat.size(),n=mat[0].size();
int left=0,right=0;
for(int i=0;i<m;i++) left+=mat[i][0],right+=mat[i].back();
int init=left;
while(left<right){
int mid=(left+right)>>1;
int num=1;
dfs(mid,0,init,num,k);
if(num>=k) right=mid;
else left=mid+1;
}
return left;
}
void dfs(int mid,int index,int sum,int& num,int k){
if(sum>mid||index==m||num>k) return;
dfs(mid,index+1,sum,num,k);
for(int i=1;i<n;i++){
if(sum+temp[index][i]-temp[index][0]<=mid){
num++;
dfs(mid,index+1,sum+temp[index][i]-temp[index][0],num,k);
}else{
break;
}
}
}
};
|
作者:newbie-19
链接:https://leetcode-cn.com/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/solution/er-fen-by-newbie-19-3/
总结
仅AC前两题,排名 1039/3108。
迟到了1分钟,前2题用了8分钟。第3题大概写了10多分钟没写出来就没写了,因为大伯和伯妈要坐12点的火车,陪他们吃完饭就去送他们了,顺便拿我的车票。
文章作者
Single Long
上次更新
2020-07-31
(6e089dc)
Update Leetcode reviews
许可协议
CC BY-NC-ND 4.0