wy的leetcode刷题记录_Day80
声明
本文章的所有题目信息都来源于leetcode
如有侵权请联系我删掉!
时间:2024-3-2
前言
目录
- wy的leetcode刷题记录_Day80
- 声明
- 前言
- 2368. 受限条件下可到达节点的数目
- 题目介绍
- 思路
- 代码
- 收获
- 92. 反转链表 II
- 题目介绍
- 思路
- 代码
- 收获
2368. 受限条件下可到达节点的数目
今天的每日一题是:2368. 受限条件下可到达节点的数目
题目介绍
现有一棵由 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 到达。
思路
DFS:按照题目要求进行模拟进行树上DFS,根据题目提供的节点数目及边的位置构建邻接表,然后dfs遍历整个邻接表,遍历到不可抵达的节点时结束dfs。其中有细节就是dfs邻接表时可能会出现1->2->1这种死循环情况,除了本身树成环的情况我们只需要在dfs基础上加一个变量记录上一次遍历的节点以此判断是否进入死循环即可。
代码
class Solution {
public:int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {vector<vector<int>> LinkList(n);//邻接表vector<int> is_restricted(n);int ans=0;for(auto x:restricted){is_restricted[x]=1;}LinkList.resize(n);for(auto v:edges){LinkList[v[0]].push_back(v[1]);LinkList[v[1]].push_back(v[0]);}function<void(int,int)> dfs = [&](int x,int f){ans++;for(auto y:LinkList[x]){if(y != f && !is_restricted[y]){dfs(y,x);}}};dfs(0,-1);// int ans=dfs(0);return ans;}
};
收获
树上DFS配合邻接表。
92. 反转链表 II
92. 反转链表 II
题目介绍
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
示例 2:
输入:head = [5], left = 1, right = 1
输出:[5]
思路
其实就是反转链表的衍生题目,将链表中的子链表进行反转,思路很简单但是做法比较麻烦。首先我们将这个子链表找到,将整个链表切分为了三部分:首部,反转部,尾部。将反转部反转后重新与首部尾部进行连接即可。细节就是在切分三部分的时候我们需要确定四个节点的位置:反转部首部节点和其上一个节点,反转部尾部节点和其下一个节点,记住切分一定得把反转部完全切出来要置首部的尾节点和尾部的首节点为空,否则调用反转的时候会导致整个后半部分全部反转。其次就是left为1可能会导致数组上溢,因此采用哑节点来解决。
代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:void reverserList(ListNode *head){ListNode* pre=nullptr;ListNode* cur=head;while(cur){ListNode* nexxt=cur->next;cur->next=pre;pre=cur;cur=nexxt;}}ListNode* reverseBetween(ListNode* head, int left, int right) {ListNode* dom=new ListNode(0,head);ListNode* leftHeadpre=dom;ListNode* rightTailnext=nullptr;ListNode* leftHead=nullptr;ListNode* rightTail=nullptr;//定点head=dom;for(int i=0;i<left-1;i++){head=head->next;}leftHeadpre=head;for(int i=0;i<right-left+1;i++){head=head->next;}rightTail=head;leftHead=leftHeadpre->next;rightTailnext=rightTail->next;//切断leftHeadpre->next=nullptr;rightTail->next=nullptr;reverserList(leftHead);//反转//连接leftHeadpre->next=rightTail;leftHead->next=rightTailnext;return dom->next;}
};
收获
在链表中哑节点真好用!!!!