算法训练day4: LeetCode 24
算法训练day4: LeetCode 24.19.142.面试题07.02
24.两两交换链表中的结点
题目
题解
- 第一想法:模拟的方法,使用三个指针,将结点两两交换。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode* cur=dummyhead;
while(cur->next!=NULL&&cur->next->next!=NULL) //判断是否有结点能够被交换
{
ListNode*ptr1=cur->next; //前一个交换结点
ListNode*ptr2=cur->next->next; //后一个被交换结点
cur->next =ptr2; //交换操作
ptr1->next=ptr2->next;
ptr2->next=ptr1;
cur=cur->next->next;
}
return dummyhead->next;
}
};
-
一遍AC还是挺开心的,但是我之前做过。。。
-
第二想法:
-
卡哥使用两个指针分别标记待交换的第二个结点,和下一组的第一个结点
ListNode* tmp = cur->next; // 记录临时节点 ListNode* tmp1 = cur->next->next->next; // 记录临时节点 cur->next = cur->next->next; // 步骤一 cur->next->next = tmp; // 步骤二 cur->next->next->next = tmp1; // 步骤三
我感觉读起来不是特别舒服
-
原先想在循环外设置ptr1和ptr2,使循环条件不好设置。
-
19.删除链表的倒数第N个节点
题目
题解
-
第一想法:
-
- 找到尾结点,向前找第n个
- 开辟指针数组,遍历时将地址存在数组中,遍历结束后直接在数组中取地址
-
-
第二想法:
-
妙!双指针虽然用过多次但是没有想到...
-
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* dummyhead=new ListNode(0); dummyhead->next=head; ListNode*slow=dummyhead; ListNode*fast=dummyhead; while( n-- && fast != NULL) { fast=fast->next; } fast=fast->next; while(fast!=NULL) { fast=fast->next; slow=slow->next; } ListNode* p=slow->next; slow->next=slow->next->next; delete p; return dummyhead->next; } };
-
面试题02.07链表相交
题目
题解
-
第一想法: 设两条链分支分别为a,b共有长度为c
-
- 暴力求解-如果两条链分支较短会比较快 a*b;
- 遍历指针,找到链表末尾,反向寻找 分支长比较快 max(a,b)+m;
-
-
第二想法:
-
感觉自己脑子里只有简单粗暴的遍历,一点数学思想都没有。。。
-
class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *p_A = headA; ListNode *p_B = headB; int len_A = 0; int len_B = 0; int gap = 0; while (p_A != nullptr) { len_A++; p_A = p_A->next; } while (p_B != nullptr) { len_B++; p_B = p_B->next; } if (len_A >= len_B) // 可替换 { gap = len_A - len_B; p_A = headA; p_B = headB; } else { gap = len_B - len_A; p_A = headB; p_B = headA; } // /* 替换成 p_A = headA; p_B = headB; if (len_A < len_B) { swap(p_A, p_B); swap(len_A, len_B); } gap=len_A-len_B; */ while (gap--) { p_A = p_A->next; } while (p_A != nullptr) { if (p_A == p_B) return p_A; p_A = p_A->next; p_B = p_B->next; } return nullptr; } };
-
142.环形链表
题目
题解
-
第一想法:无
-
第二想法:不是很理解
-
class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode* fast=head; ListNode* slow=head; while(fast!=NULL&&fast->next!=NULL) { slow = slow->next; fast=fast->next->next; if(slow==fast) { ListNode*index1=fast; ListNode*index2=head; while(index1!=index2) { index1 = index1 -> next; index2 = index2 -> next; } return index2; } } return NULL; } };
-
总结
前三道题还好,感觉对指针用的更熟练了,,,第四题理解了大概。