• 链表OJ题


    1.合并两个有序链表

    链接:

    https://leetcode.cn/problems/merge-two-sorted-lists/description/

    题目描述:

     

    思路1:

    遍历其中一个链表,分别进行头插,尾插和中间插入到另一个链表中

    代码1: 

    1. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    2. if (list1 == NULL && list2 == NULL)
    3. {
    4. return NULL;
    5. }
    6. if (list1 == NULL)
    7. {
    8. return list2;
    9. }
    10. if (list2 == NULL)
    11. {
    12. return list1;
    13. }
    14. struct ListNode* cur1 = list1; // 遍历list1链表
    15. struct ListNode* next1 = cur1->next; // cur1的下一个节点
    16. struct ListNode* cur2 = list2; // 遍历list2链表
    17. struct ListNode* next2 = cur2->next; // cur2的下一个节点
    18. while (cur2)
    19. {
    20. // 头插
    21. if (cur2->val <= list1->val)
    22. {
    23. cur2->next = list1;
    24. cur1 = list1 = cur2;
    25. next1 = cur1->next;
    26. cur2 = next2;
    27. if (next2)
    28. next2 = next2->next;
    29. }
    30. // 尾插
    31. else if (cur2->val > cur1->val && next1 == NULL)
    32. {
    33. cur1->next = cur2;
    34. return list1;
    35. }
    36. // 中间插入
    37. else if (cur2->val >= cur1->val && cur2->val <= next1->val)
    38. {
    39. cur1->next = cur2;
    40. cur2->next = next1;
    41. cur1 = cur1->next;
    42. cur2 = next2;
    43. if (next2)
    44. next2 = next2->next;
    45. }
    46. else
    47. {
    48. cur1 = cur1->next;
    49. next1 = next1->next;
    50. }
    51. }
    52. return list1;
    53. }

    思路2:

    利用归并排序的思维,遍历比较两个链表,将val小的节点链接到新的链表上

    代码2:

    1. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    2. // 空链表直接返回
    3. if (list1 == NULL)
    4. {
    5. return list2;
    6. }
    7. if (list2 == NULL)
    8. {
    9. return list1;
    10. }
    11. struct ListNode* head = NULL;
    12. struct ListNode* tail = head; // 标记新链表的尾节点
    13. struct ListNode* cur1 = list1, * cur2 = list2; // 遍历比较两个链表
    14. // 归并排序
    15. while (cur1 && cur2)
    16. {
    17. if (cur1->val <= cur2->val)
    18. {
    19. // 第一次尾插
    20. if (head == NULL)
    21. {
    22. head = tail = cur1;
    23. cur1 = cur1->next;
    24. }
    25. else
    26. {
    27. tail->next = cur1;
    28. tail = tail->next;
    29. cur1 = cur1->next;
    30. }
    31. }
    32. else
    33. {
    34. // 第一次尾插
    35. if (head == NULL)
    36. {
    37. head = tail = cur2;
    38. cur2 = cur2->next;
    39. }
    40. else
    41. {
    42. tail->next = cur2;
    43. tail = tail->next;
    44. cur2 = cur2->next;
    45. }
    46. }
    47. }
    48. // cur1先遍历完就直接链接上cur2剩余部分,反之亦然
    49. if (cur1 == NULL)
    50. {
    51. tail->next = cur2;
    52. }
    53. if (cur2 == NULL)
    54. {
    55. tail->next = cur1;
    56. }
    57. return head;
    58. }

    2.链表分割

    链接:

    https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

    题目描述:

    思路:

    1.设置两个带头节点的新链表

    2.将比x小的插入到A链表中,比x大的插入到B链表中

    3.链接两个链表并返回,并释放头节点

    代码:

    1. class Partition {
    2. public:
    3. ListNode* partition(ListNode* pHead, int x) {
    4. // write code here
    5. // 设置两个带有哨兵卫的头节点
    6. struct ListNode* cur = pHead;
    7. struct ListNode* less_head, * less_tail, * greater_head, * greater_tail;
    8. less_head = less_tail = (struct ListNode*)malloc(sizeof(struct ListNode));
    9. greater_head = greater_tail = (struct ListNode*)malloc(sizeof(struct ListNode));
    10. // 分别尾插到新链表
    11. while (cur)
    12. {
    13. if (cur->val < x)
    14. {
    15. less_tail->next = cur;
    16. less_tail = cur;
    17. }
    18. else
    19. {
    20. greater_tail->next = cur;
    21. greater_tail = cur;
    22. }
    23. cur = cur->next;
    24. }
    25. // 链表合并
    26. less_tail->next = greater_head->next;
    27. greater_tail->next = NULL;
    28. struct ListNode* head = less_head->next;
    29. free(less_head);
    30. free(greater_head);
    31. return head;
    32. }
    33. };

    3.回文链表

    链接:

    https://leetcode.cn/problems/palindrome-linked-list/ 

    题目描述:

    思路:

    1.找到中间节点

    2.反转一半的链表

    3.将一半链表与另一半反转后的链表进行比较

    代码: 

    1. bool isPalindrome(struct ListNode* head){
    2. // 计算链表节点个数
    3. int num = 0;
    4. struct ListNode* cur = head;
    5. while (cur)
    6. {
    7. cur = cur->next;
    8. num++;
    9. }
    10. // 反转一半的链表
    11. cur = head;
    12. struct ListNode* newhead = NULL;
    13. int half_num = num / 2;
    14. while (half_num)
    15. {
    16. struct ListNode* next = cur->next;
    17. cur->next = newhead;
    18. newhead = cur;
    19. cur = next;
    20. half_num--;
    21. }
    22. // 比较
    23. if (num % 2 != 0)
    24. {
    25. cur = cur->next;
    26. }
    27. while (newhead)
    28. {
    29. if (newhead->val == cur->val)
    30. {
    31. cur = cur->next;
    32. newhead = newhead->next;
    33. }
    34. else
    35. {
    36. return false;
    37. }
    38. }
    39. return true;
    40. }

    4.相交链表

    链接:

    https://leetcode.cn/problems/intersection-of-two-linked-lists/ 

    题目描述:

    思路: 

    1.分别计算两个链表的节点数目

    2.让长链表先走节点数目的差距步

    3.然后同时开始向后比较节点的地址 

    代码: 

    1. struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    2. // 计算链表节点数
    3. int numA = 1, numB = 1;
    4. struct ListNode* curA = headA, * curB = headB;
    5. while (curA->next)
    6. {
    7. curA = curA->next;
    8. numA++;
    9. }
    10. while (curB->next)
    11. {
    12. curB = curB->next;
    13. numB++;
    14. }
    15. // 找出长链表和短链表
    16. struct ListNode* long_list = numA > numB ? headA : headB;
    17. struct ListNode* short_list = numA <= numB ? headA : headB;
    18. // 长链表走过两链表的差距步
    19. int gap = abs(numA - numB);
    20. while (gap--)
    21. {
    22. long_list = long_list->next;
    23. }
    24. // 比较两个链表的节点地址
    25. while (long_list && short_list)
    26. {
    27. if (long_list == short_list)
    28. {
    29. return long_list;
    30. }
    31. else
    32. {
    33. long_list = long_list->next;
    34. short_list = short_list->next;
    35. }
    36. }
    37. return NULL;
    38. }

    5.环形链表

    链接:

    https://leetcode.cn/problems/linked-list-cycle/submissions/ 

    题目描述:

    思路:

    1.快指针一次走两步,慢指针一次走两步,这样在环中两个指针始终会相遇

    代码: 

    1. bool hasCycle(struct ListNode *head) {
    2. struct ListNode* slow = head, * fast = head;
    3. while (fast && fast->next)
    4. {
    5. slow = slow->next;
    6. fast = fast->next->next;
    7. if (slow == fast)
    8. {
    9. return true;
    10. }
    11. }
    12. return false;
    13. }

     

  • 相关阅读:
    【Java初阶】Array详解(下)
    MATLAB算法实战应用案例精讲-【数模应用】数据中台模型建设
    Selenium安装WebDriver最新Chrome驱动(含116/117/118/119)
    Nmap(端口扫描工具)在Windows上的安装和使用,so easy
    【C语言刷LeetCode】453. 最小操作次数使数组元素相等(M)
    别再到处乱放配置文件了!我司使用 7 年的这套解决方案,稳的一秕
    DevOps CI/CD之一: Jenkins和Github
    TCP/IP网络分层模型
    【培训】MMEdu离线版的使用:实现石头剪刀布图像分类的生成模型
    MyBatisPlus一个依赖轻松搞定权限问题
  • 原文地址:https://blog.csdn.net/l_shadow_m/article/details/126491967