链表题目小结

来源:互联网 发布:淘宝淘管家在哪里找到 编辑:程序博客网 时间:2024/05/05 21:47

1. 求单链表中节点的个数

2. 将单链表反转

3. 查找单链表中的倒数第K个节点(k > 0)

4. 查找单链表的中间节点

5. 从尾到头打印单链表

6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序

7. 判断一个单链表中是否有环

8. 判断两个单链表是否相交

9. 求两个单链表相交的第一个节点

10. 已知一个单链表中存在环,求进入环中的第一个节点

11. 删除单向链表中间的某个节点,假定你只能访问该节点

12. 检查链表是否为回文

13. 移除未排序链表中的重复节点

14. 给定两个用链表表示的整数,每个节点包含一个数位,这些数位是方向存放的,对这两个整数求和,并用链表形式返回结果


链表节点定义:

typedef struct ListNode {int value;struct ListNode *next;}ListNode;

1. 求单链表中结点的个数

int getListLength(ListNode *head) {if (head == NULL)return 0;ListNode *p = head;int count = 0;while (p) {count++;p = p->next;}return count;}

2. 将单链表反转

ListNode* reverseList(ListNode *head) {if (head == NULL)return head;ListNode *rHead = NULL;ListNode *p = head;while (p) {ListNode *t = p;p = p->next;t->next = rHead;rHead = t;}return rHead;}

3. 查找单链表中的倒数第K个结点(k > 0)

ListNode* getKthNodeFromEnd(ListNode *head, int k){if (head == NULL || k <= 0)return head;ListNode *slow = head;ListNode *fast = head;while (k > 0 && fast != NULL) {fast = fast->next;k--;}if (k > 0)return NULL;if (fast == NULL) {return slow;}while (fast->next) {slow = slow->next;fast = fast->next;}return slow->next;}


4. 查找单链表的中间结点

ListNode* getMidNode(ListNode *head) {ListNode *slow = head;ListNode *fast = head;while (fast && fast->next) {fast = fast->next->next;slow = slow->next;}return slow;}

5. 从尾到头打印单链表

void reversePlayList(ListNode *head) {if (head == NULL)return;PrintListFromEnd(head->next);printf("%d ", head->value);}

6. 已知两个单链表head1和head2各自有序,把它们合并成一个链表依然有序

ListNode* mergeLists(ListNode *head1, ListNode *head2) {ListNode *head = NULL;ListNode *p = NULL;ListNode *t;while (head1 && head2) {if (head1->value < head2->value) {                        if (head == NULL) {head = p = head1;}t = head1;head1 = head1->next;} else {if (head == NULL) {head = p = head2;}t = head2;head2 = head2->next;}p->next = t;p = t;}if (head1 == NULL)p->next = head2;if (head2 == NULL)p->next = head1;return head;}



7. 判断一个单链表中是否有环

bool hasCircle(ListNode *head) {ListNode *slow = head;ListNode *fast = head;while (fast && fast->next) {fast = fast->next->next;slow = slow->next;if (fast == slow) //有环快慢指针必相遇return true;}return false;}

8. 判断两个单链表是否相交

bool isIntersect(ListNode *head1, ListNode *head2) {if (head1 == NULL || head2 == NULL)return false;while (head1->next)head1 = head1->next;while (head2->next)head2 = head2->next;return head1 == head2; //若相交,最后一个节点必为两者所有}

9. 求两个单链表相交的第一个节点

ListNode* getFirstCommonNode(ListNode *head1, ListNode *head2) {if (head1 == NULL || head2 == NULL)return NULL;int len1 = 0, len2 = 0;ListNode *p1 = head1;ListNode *p2 = head2;while (p1) {len1++;p1 = p1->next;} while (p2) {len2++;p2 = p2->next;}if (p1 != p2)return NULL;p1 = head1;p2 = head2;if (len1 > len2) {int k = len1 - len2;while (k--)p1 = p1->next;} else {int k = len2 - len1;while (k--)p2 = p2->next;}while (p1 != p2) {p1 = p1->next;p2 = p2->next;}return p1;}

10. 已知一个单链表中存在环,求进入环中的第一个节点

从环中相遇的节点,把链表分开,转成求两链表的相交的第一个节点

ListNode* getFirstNodeInCircle(ListNode *head) {if (head == NULL || head->next == NULL)return NULL;ListNode *fast = head;ListNode *slow = head;while (fast->next->next) {fast = fast->next->next;slow = slow->next;if (fast == slow)break;}if (fast != slow)return NULL;ListNode *p1 = head;ListNode *p2 = fast->next;int len1 = 1;int len2 = 1;while (p1 != slow) {p1 = p1->next;len1++;}while (p2 != slow) {p2 = p2->next;len2++;}p1 = head;p2 = fast->next;if (len1 > len2) {int k = len1 - len2;while (k--)p1 = p1->next;} else {int k = len2 - len1;while (k--)p2 = p2->next;}while(p1 != p2) {p1 = p1->next;p2 = p2->next;}return p1;}

11. 删除单向链表中间的某个节点,假定你只能访问该节点

用下一个节点覆盖该节点,当该节点为尾节点时,无法操作

bool deleteNode(ListNode *node) {if (node == NULL || node->next == NULL)return false;ListNode *p = node->next;node->value = p->value;node->next = p->next;delete p;return true;}

12. 检查链表是否为回文

反转链表,然后和原链表比较


13. 移除未排序链表中的重复节点

void deleteDups(ListNode *head) {if (head == NULL || head->next == NULL)return;map<int, ListNode *> listMap;ListNode *p = head;ListNode *temp;listMap[p->value] = p;while (p->next) {if (listMap.find(p->next->value)) {temp = p->next;p->next = p->next->next;delete temp;} else {listMap[p->next->value] = p->next;}p = p->next;}}

14. 给定两个用链表表示的整数,每个节点包含一个数位,这些数位是方向存放的,对这两个整数求和,并用链表形式返回结果

ListNode* addTwoNumbers(ListNode *head1, ListNode *head2) {ListNode *header = new ListNode(-1);ListNode *result = header;int val = 0;int extra = 0;while (head1 || head2) {val = (head1 != NULL ? head1->value : 0) + (head2 != NULL ? head2->value : 0) + extra;extra = val / 10;val %= 10;ListNode *node = new ListNode(val);node->value = val;result->next = node;result = result->next;if (head1) {head1 = head1->next;}if (head2) {head2 = head2->next;}}    if (extra > 0) {ListNode *node = new ListNode(extra);result->next = node;}result = header->next;delete header;return result;}


0 0