携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
leetcode_第 305 场周赛
第 305 场周赛
竞赛时间只做了两个题出来了,得分7,排名3788/7465,我好菜啊!!!!!!!!!!!!!!!!
题目1 算术三元组的数目
给你一个下标从 0 开始、严格递增 的整数数组 nums 和一个正整数 diff 。如果满足下述全部条件,则三元组 (i, j, k) 就是一个 算术三元组 :
i < j < k ,
nums[j] - nums[i] == diff 且
nums[k] - nums[j] == diff
返回不同 算术三元组 的数目。
示例 1
输入:nums = [0,1,4,6,7,10], diff = 3
输出:2
解释:
(1, 2, 4) 是算术三元组:7 - 4 == 3 且 4 - 1 == 3 。
(2, 4, 5) 是算术三元组:10 - 7 == 3 且 7 - 4 == 3 。
示例 2
输入:nums = [4,5,6,7,8,9], diff = 2
输出:2
解释:
(0, 2, 4) 是算术三元组:8 - 6 == 2 且 6 - 4 == 2 。
(1, 3, 5) 是算术三元组:9 - 7 == 2 且 7 - 5 == 2 。
提示:
3 <= nums.length <= 2000 <= nums[i] <= 2001 <= diff <= 50nums严格 递增
class Solution {
public int arithmeticTriplets(int[] nums, int diff) {
//时间O(n) 空间O(n)
HashSet<Integer> set = new HashSet<>();
int res = 0;
for(int i = 0; i < nums.length; i++) {
set.add(nums[i]);
if(set.contains(nums[i]-diff)&&set.contains(nums[i]-diff-diff)) {
res++;
}
}
return res;
}
}
解析
这个题并没有什么难度,用set添加后一直查找就可以了,时间复杂度O(n)空间复杂度O(n),考完看别人的解析,可以做三指针,没太看懂,空间复杂度可以为O(1)。
题目2 受限条件下可到达节点的数目
现有一棵由 n 个节点组成的无向树,节点编号从 0 到 n - 1 ,共有 n - 1 条边。
给你一个二维整数数组 edges ,长度为 n - 1 ,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在一条边。另给你一个整数数组 restricted 表示 受限 节点。
在不访问受限节点的前提下,返回你可以从节点 0 到达的 最多 节点数目。
注意,节点 0 不 会标记为受限节点。
示例 1
输入:n = 7, edges = [[0,1],[1,2],[3,1],[4,0],[0,5],[5,6]], restricted = [4,5]
输出:4
解释:上图所示正是这棵树。
在不访问受限节点的前提下,只有节点 [0,1,2,3] 可以从节点 0 到达。
示例 2
输入:n = 7, edges = [[0,1],[0,2],[0,5],[0,4],[3,2],[6,5]], restricted = [4,2,1]
输出:3
解释:上图所示正是这棵树。
在不访问受限节点的前提下,只有节点 [0,5,6] 可以从节点 0 到达。
class Solution {
public int reachableNodes(int n, int[][] edges, int[] restricted) {
HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();
int min = 0;
int max = 0;
for(int i = 0; i < edges.length;i++){
min = Math.min(edges[i][0],edges[i][1]);
max = Math.max(edges[i][0],edges[i][1]);
if(!map.containsKey(min) ) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(max);
map.put(min, integers);
} else {
map.get(min).add(max);
}
if(!map.containsKey(max) ) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(min);
map.put(max, integers);
} else {
map.get(max).add(min);
}
}
HashSet<Integer> res = new HashSet<>();
HashSet<Integer> restrictedset = new HashSet<>();
for (int i = 0; i < restricted.length; i++) {
restrictedset.add(restricted[i]);
}
ArrayList<Integer> integers = map.get(0);
res.add(0);
for (Integer i : integers) {
myAdd(res,restrictedset,map,i);
}
return res.size();
}
public void myAdd(HashSet<Integer> res,HashSet<Integer> restrictedset , HashMap<Integer, ArrayList<Integer>> map,Integer i) {
if(restrictedset.contains(i)||res.contains(i)) {
return;
} else {
res.add(i);
ArrayList<Integer> integers = map.get(i);
if(integers==null) return;
for (Integer j : integers) {
myAdd(res,restrictedset,map,j);
}
}
}
}
解析
我做的思路可能有一点复杂,我用map把每个值能去的路都记录了,比如map中key=1的value的数组记录了和1相连的所有值,之后从0开始遍历他所能去的值,判断是否在限制的数组内,如果不再就添加到resset内,循环往下一直遍历能走的值,最后返回resset的大小就是结果了。
============================================================ 手动分界线,自己就做到了这里,两个题花了1个小时,还罚时了10分钟。
以下第三题是后面看别人题解做的
题目3检查数组是否存在有效划分
给你一个下标从 0 开始的整数数组 nums ,你必须将数组划分为一个或多个 连续 子数组。
如果获得的这些子数组中每个都能满足下述条件 之一 ,则可以称其为数组的一种 有效 划分:
子数组 恰 由 2 个相等元素组成,例如,子数组 [2,2] 。
子数组 恰 由 3 个相等元素组成,例如,子数组 [4,4,4] 。
子数组 恰 由 3 个连续递增元素组成,并且相邻元素之间的差值为 1 。例如,子数组 [3,4,5] ,但是子数组 [1,3,5] 不符合要求。
如果数组 至少 存在一种有效划分,返回 true ,否则,返回 false 。
示例 1
输入:nums = [4,4,4,5,6]
输出:true
解释:数组可以划分成子数组 [4,4] 和 [4,5,6] 。
这是一种有效划分,所以返回 true 。
示例 2
输入: nums = [1,1,1,2]
输出: false
解释: 该数组不存在有效划分。
class Solution {
public boolean validPartition(int[] nums) {
boolean[] dp = new boolean[nums.length + 1];
dp[0] = true;
dp[1] = false;
dp[2] = nums[1] == nums[0];
for(int i = 2; i < nums.length; i++) {
if(dp[i-1] && nums[i]==nums[i-1]) {
dp[i+1] = true;
continue;
}
if(i > 1 && dp[i-2] && nums[i] == nums[i-1] + 1 && nums[i]==nums[i-2] + 2) {
dp[i+1] = true;
continue;
}
if(i > 1 && dp[i-2] && nums[i] == nums[i-1] && nums[i]==nums[i-2]) {
dp[i+1] = true;
continue;
}
}
return dp[nums.length];
}
}
解析
用一个dp数组记录能不能有效划分,如果数组长度为0,算已经有效划分。数组为1,则false,数组为2时,nums[1]==nums[0]就时有效划分。
当n > 2时 db[i]的值与前1个和前两个db有关
情况一如果dp[i-1]为真,并且,nums[i] = nums[i-1]那么 nums[i] 加入后也可以有效划分,所有db[i]也是真
情况二如果dp[i-1]为假,但是dp[i-2]为真,现在需要判断三个数,nums[i]、nums[i-1]、nums[i-2]他们如果相等,或者递增,也是可以有效划分。对应代码为最后一个if块。
不得不说大佬的思路就是强。
3.结束
太菜了,,,,希望快点进步,什么时候能稳定做出三个题就好了。