单链表 以及用链表解决常用面试算法的问题
单链表在插入和删除的时候容易出现空指针异常
1.当进行链表插入的时候
newNode->next=p->next; p->next=newNode //当插入首个节点的时候需要注意 if(head==NULL) head=newNode;
2.当在删除链表的时候需要注意链表的表尾问题
if(head->next==NULL) { head=NULL; }
3 在使用链表的过程中边界问题是需要判断的
4. 当引入哨兵的时候可以通过技巧跳过边界问题,在头结点的前面加入一个哨兵节点,哨兵节点不参与实际数据,有了哨兵节点,在添加元素的时候就不需要判断链表边界问题
链表的反转
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { ListNode *cur; ListNode *pre=NULL; ListNode *next=NULL; if(head==NULL){ return NULL; } cur=head; while(cur->next!=NULL){ next=cur->next; cur->next=pre; pre=cur; cur=next; } cur->next=pre; return cur; } };
两个有序链表的合并,参考LeetCode解,加入哨兵,防止边界报空
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode head(0); ListNode* node=&head; while(l1 && l2){ ListNode ** nextNode=l1->val > l2->val?&l2:&l1; node->next= *nextNode; *nextNode = (*nextNode)->next; node = node->next; } node->next = (l1!=NULL)?l1:l2; return head.next; } };
环形链表
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { ListNode* slow=head, *fast=head; while (slow && fast && fast->next) { slow=slow->next; fast=fast->next->next; if(slow==fast) return true; } return false; } };
删除链表中的第k个节点,加入哨兵,防止边界报空问题
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode *newNode=new ListNode(0); newNode->next=head; ListNode* first=newNode; ListNode* second=newNode; for(int i=0;i<n+1;i++){ first=first->next; } while(first!=NULL){ first=first->next; second=second->next; } second->next=second->next->next; return newNode->next; } };