题目分析:
我们要在两个链表中找到第一个公共的节点,采用双指针法来实现。我们
p1先遍历headA,然后遍历headB
p2 先遍历headB,然后遍历headA
要是有重合的节点,他们就会相遇
- class Solution {
- public:
- ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
-
- ListNode* p1 = headA;
- ListNode* p2 = headB;
- /*p1先遍历headA,然后遍历headB
- p2 先遍历headB,然后遍历headA
- 要是有重合的节点,他们就会相遇*/
- while(p1 != p2){
-
- if(p1) p1 = p1 -> next;
- else p1 = headB;
-
-
- if(p2) p2 = p2 -> next;
- else p2 = headA;
-
- }
- return p1;//返回我们共同节点的节点的指针
-
- }
- };
题目分析:
就是怎么把链表倒着打印输出
1、使用insert函数倒着插入
2、使用容器的算法将容器倒着输出
3、将数据存放到栈里面,然后就可以实现倒着打印
- class Solution {
- public:
- vector<int> reversePrint(ListNode* head) {
-
- vector<int> v1;
-
-
- while(head){
-
- v1.insert(v1.begin(),head->val);//在v1.begin()位置之前插入字符head—>val,这样就是倒序
-
- head = head ->next;
-
- }
-
- return v1;
-
- }
- };
- class Solution {
- public:
- vector<int> reversePrint(ListNode* head) {
-
- vector<int> v1;
-
-
- while(head){
-
- v1.push_back(head->val);
-
- head = head ->next;
-
- }
-
- return vector<int>(v1.rbegin(),v1.rend());//将容器倒着输出rbegin,rend就是倒序的意思
-
- }
- };
- class Solution {
- public:
- vector<int> reversePrint(ListNode* head) {
-
- vector<int> v1;
- stack<int>stk;//创建一个栈的容器
-
- while(head){
-
- stk.push(head ->val);//元素入栈
- head = head ->next;
-
- }
- int len = stk.size();
- for( int i = 0; i<len;i++){
- v1.push_back(stk.top());//将栈顶元素后插进容器中
- stk.pop();
- }
- return v1;
-
-
- }
- };
题目分析:
需要我们找到链表的倒数第k个元素,这样我们可以使用双指针法,让两个指针之间的距离相差k个单位,等我们远处的指针指向了链表尾部空的位置,我们近处的指针就是倒数第k个单位
- //front与later之间的距离是k,倒数的话就是我们后指针指向空,这样前后指针指向最后k个
- class Solution {
- public:
- ListNode* getKthFromEnd(ListNode* head, int k) {
- ListNode* front = head;//近处指针
- ListNode* later = head;//远处指针
- while (k-- && front != NULL)
- front= front->next; // front1 先移动k位
- while (front != NULL) { // front与 later同时移动,直到later指向尾端
- front = front->next;
- later = later->next;
- }
- return later; // 此时later 就是第k个节点起始位置
- }
- };
剑指 Offer 24. 反转链表https://leetcode.cn/problems/fan-zhuan-lian-biao-lcof/
题目分析:
我们只需要将指针指向的方向反过来就可以实现
我们需要将cur指针指向的节点间的指针反向,因为我们cur指针已经被破坏,不能指针利用前进,只能将下一个节点的地址保存起来
- class Solution {
- public:
- ListNode* reverseList(ListNode* head) {
-
- ListNode* pre = nullptr;
- ListNode* cur =head;
-
- while(cur){
- ListNode*later = cur ->next;
- cur->next = pre;//指针反转
- pre = cur;
- cur = later;
- }
- return pre;
-
- }
- };
21. 合并两个有序链表https://leetcode.cn/problems/merge-two-sorted-lists/
题目解析:
我们就好比是球球大作战里面的一个大球,我们面对有两个队伍,先判断哪个队伍前面的最小,就去吃那个,在两个队伍之间反复横跳,吃我一个我们就变胖一些,就这样一直吃完两个队伍
- class Solution {
- public:
- ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
- ListNode* preHead = new ListNode(-1);.//吃货节点preHead
-
- ListNode* prev = preHead;
- //当两条链表都存在的情况下
- while (l1 != nullptr && l2 != nullptr) {
- if (l1->val < l2->val) {
- prev->next = l1;
- l1 = l1->next;//l1的现节点指针移动
- } else {
- prev->next = l2;//新链表的当前节点指针指向l2
- l2 = l2->next;//l2的现节点指针移动
- }
- prev = prev->next;//吃掉一个节点
- }
- //下面是只剩下一条或者一条都没有
- // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
- prev->next = l1 == nullptr ? l2 : l1;// l1为空的话第三条的指针就指向l2的剩余部分,反之亦然
-
- return preHead->next;//返回第三条链表的第二个节点
- }
- };
剑指 Offer 35. 复杂链表的复制https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/
题目分析:
要复制出一个链表
1、在原来链表的节点之后创建一个空间,并且赋给同样的值,这样的话
2、随机指针
3、next指针,并且把原来的链表去掉,只留下新的复制链表
- class Solution {
- public:
- Node* copyRandomList(Node* head)
- {
- /*1、复制每个节点,也就是在两个节点之间新建一个节点,复制前驱节点 */
- for(auto p = head; p;)//定义一个p,循环执行的条件是p存在
- {
- auto newp = new Node(p ->val);//创建一个节点,并且赋给val
- //在节点之间插入新节点
- auto temp = p ->next;//因为我们要在插入一个节点,后面的节点无法通过next指针访问了,只能保存 下一个节点的地址
- p ->next = newp;//指针指向新节点
- newp ->next = temp;
- p = temp;//p跳到下一个要插入的位置之前
- }
- /*2、开始设置复制节点的random指针*/
- for(auto p = head;p; p = p ->next->next)
- {
- if(p ->random)
- {
- p ->next->random = p ->random ->next;//random指针的指向
- }
- }
- /*3、从旧链表中分离出我们新生的复制链表,也就是指针只指向我们复制的新生节点*/
- Node* dummy = new Node(-1);//头节点
- Node* cur = dummy;
-
- for( auto p = head; p; p = p ->next)//p更新
- //p是旧链表的指针,cur是新链表的指针
- {
- cur ->next = p ->next;//p->next就是我们复制生成的节点
- cur = cur ->next;//cur更新
- p ->next = p ->next ->next;//p指针执行下一个p
- }
- return dummy->next;
- }
- };