• 被火车撞了都不能忘记的几道题(你会了吗?)


    目录

    一.删除有序链表中的重复元素I

    二.删除有序链表重复元素II

    三.环形单链表中插入一个元素

    四.单链表翻转II

    五.奇偶链表


    一.删除有序链表中的重复元素I

    1.对应牛客网链接:

    删除有序链表中重复的元素-I_牛客题霸_牛客网 (nowcoder.com)

    2.题目描述:

     3.解题思路

    1.定义一个cur和next指针一开始cur指向头,next指针指向头的下一个

    2.边遍历边比较 cur->val == next->val若相等,则将 cur 就指向 next 的下一个节点,否则继续遍历,直至遍历完整个链表。

    下面以1->2->3->3->4为例:

    由于 cur 指向的节点的值(1)不等于 next 指向的节点的值(2),两个指针右移

    不相等继续后移

    相等,cur 指向 next 的下一节点(相当于删除链表中的重复元素 3),next 指针右移

    直到next为空

    4.对应代码

    1. class Solution {
    2. public:
    3. /**
    4. *
    5. * @param head ListNode类
    6. * @return ListNode类
    7. */
    8. ListNode* deleteDuplicates(ListNode* head) {
    9. // write code here
    10. if (head == nullptr || head->next == nullptr) {
    11. return head;
    12. }
    13. ListNode* cur = head;
    14. ListNode* next = head->next;
    15. while (next) {
    16. if (cur->val == next->val) { //重复
    17. while (next && next->val == next->val) {
    18. ListNode* next = cur->next; //保存下一个节点
    19. delete cur;
    20. cur = next;
    21. }
    22. cur->next = next;
    23. } else {
    24. //指针一起移动
    25. cur = next;
    26. next = next->next;
    27. }
    28. }
    29. return head;
    30. }
    31. };

    递归版本:

    1. class Solution {
    2. public:
    3. /**
    4. *
    5. * @param head ListNode类
    6. * @return ListNode类
    7. */
    8. ListNode* deleteDuplicates(ListNode* head) {
    9. // write code here
    10. if (!head || !head->next) {
    11. return head;
    12. }
    13. ListNode* next = head->next;
    14. if (head->val != next->val) {
    15. head->next = deleteDuplicates(head->next);
    16. return head;
    17. } else {
    18. while (next && next->val == head->val) {
    19. head->next = next->next;
    20. delete next;
    21. next = head->next;
    22. }
    23. head->next = deleteDuplicates(head->next);
    24. return head;
    25. }
    26. }
    27. };

    二.删除有序链表重复元素II

    1.对应牛客网链接:

    删除有序链表中重复的元素-II_牛客题霸_牛客网 (nowcoder.com)

    2.题目描述:

     3.解题思路

    1.定义一个三个指针变量:last 、prev、cur一开始分别指针空、头节点和头节点的下一个

    2.迭代变量如果prev的值和cur的值相等那么一直移动cur直到cur的值和prev不相等。如果prev的值和cur不相等则三个指针一起移动。直到cur为空

    下面我们以1->3->3->4->4->5为例:

    初始状态:

     发现prev和cur的值不相等三个指针一起移动

     此时prev和cur的值一样我们进行删除:

    删除完成之后我们发现prev和cur的值又相等了继续进行删除

     

    直到cur走到空结束循环将头节点返回即可

    注意:(如果一开始就是头删需要进行特判改变头节点) 

    4.对应代码

    1. class Solution {
    2. public:
    3. /**
    4. *
    5. * @param head ListNode类
    6. * @return ListNode类
    7. */
    8. ListNode* deleteDuplicates(ListNode* head) {
    9. // write code here
    10. if (head == nullptr || head->next == nullptr) {
    11. return head;
    12. }
    13. ListNode* prev = head;
    14. ListNode* cur = head->next;
    15. ListNode* last = nullptr;
    16. while (cur) {
    17. if (cur->val == prev->val) {
    18. while (cur && cur->val == prev->val) {//进行删除
    19. ListNode* next = cur->next;
    20. delete cur;
    21. cur = next;
    22. }
    23. delete prev;
    24. prev = cur;
    25. cur = cur ? cur->next : nullptr;
    26. if (last == nullptr) {//特判头删的情况
    27. head = prev;
    28. } else {
    29. last->next = prev;
    30. }
    31. } else {//三个指针迭代走
    32. last = prev;
    33. prev = cur;
    34. cur = cur->next;
    35. }
    36. }
    37. return head;
    38. }
    39. };

    递归版本:

    1. class Solution {
    2. public:
    3. /**
    4. *
    5. * @param head ListNode类
    6. * @return ListNode类
    7. */
    8. ListNode* deleteDuplicates(ListNode* head) {
    9. // write code here
    10. if (head == nullptr || head->next == nullptr) {
    11. return head;
    12. }
    13. if (head->val != head->next->val) {
    14. head->next = deleteDuplicates(head->next);
    15. return head;
    16. } else {
    17. //说明相等
    18. int val = head->val;
    19. while (val == head->val) {
    20. ListNode* next = head->next;
    21. delete head;
    22. head = next;
    23. if (head == nullptr)
    24. return nullptr;
    25. }
    26. return deleteDuplicates(head);
    27. }
    28. }
    29. };

    三.环形单链表中插入一个元素

    1.对应letecode链接:

    剑指 Offer II 029. 排序的循环链表 - 力扣(LeetCode)

    2.题目描述:

    3.解题思路:

     插入情况一:链表为空创建一个节点让自己指向自己

    插入情况二:单链表只有一个节点或单链表中所有节点的值都相等

    插入情况三:找到一个插入位置使其前节点值比Insertval小,后节点值比其Insertval大

    情况四:当插入节点为最小值或者最大值

    4.对应代码:

    1. class Solution {
    2. public:
    3. Node* insert(Node* head, int insertVal) {
    4. if (head == NULL) {
    5. Node* newNode = new Node(insertVal);
    6. newNode->next = newNode;
    7. return newNode;
    8. }
    9. Node* cur = head;
    10. while (1) {
    11. if (cur->next ==
    12. head) { //说明可能只有一个节点或者全是一种值的节点
    13. break;
    14. } else if (cur->val <= insertVal && cur->next->val >= insertVal) {
    15. break;
    16. } else if (cur->val > cur->next->val && (insertVal >= cur->val ||
    17. insertVal <= cur->next->val)) {
    18. break;
    19. }
    20. cur = cur->next;
    21. }
    22. cur->next = new Node(insertVal, cur->next);
    23. return head;
    24. }
    25. };

    四.单链表翻转II

    1.对应牛客网链接

    链表内指定区间反转_牛客题霸_牛客网 (nowcoder.com)

    2.题目描述:

    3.解题思路:

    1.指向 left左边元素的指针 pre ,它表示未翻转的链表,需要把当前要翻转的链表结点放到 pre 之后。

    cur 指向当前要翻转的链表结点。

    nxt 指向 cur.next ,表示下一个要被翻转的链表结点。

    tail 指向已经翻转的链表的结尾,用它来把已翻转的链表和剩余链表进行拼接

     

     4.对应代码:

    1. /**
    2. * struct ListNode {
    3. * int val;
    4. * struct ListNode *next;
    5. * };
    6. */
    7. class Solution {
    8. public:
    9. /**
    10. *
    11. * @param head ListNode类
    12. * @param m int整型
    13. * @param n int整型
    14. * @return ListNode类
    15. */
    16. ListNode*temp=nullptr;
    17. ListNode* reverseBetween(ListNode* head, int m, int n) {
    18. // write code here
    19. if(m==1)
    20. {
    21. return ReversN(head, n);
    22. }
    23. ListNode*node=reverseBetween(head->next, m-1, n-1);
    24. head->next=node;
    25. return head;
    26. }
    27. ListNode*ReversN(ListNode*head,int n)
    28. {
    29. if(n==1)
    30. {
    31. temp=head->next;//保存后面的节点
    32. return head;
    33. }
    34. ListNode*node=ReversN(head->next,n-1);
    35. //开始翻转
    36. head->next->next=head;
    37. head->next=temp;
    38. return node;
    39. }
    40. };

    递归版本:

    1.如果m ==1,就相当于反转链表的前n元素。
    2.如果m != 1我们把 head的索引视为1,那么我们是想从第m个元素开始反转,如果扎head.next的索引视为1,那相对于head.next,反转的区间3.应该是从第m-1个元素始的,以此类推,递归拼接后续已反转的链表。
    对于每次反转,如果n等于1,相当于只颠倒第一个节点,如果不是,则进入后续节点问题),将后续反转的内容接到前面即可。
    对应代码
    1. /**
    2. * struct ListNode {
    3. * int val;
    4. * struct ListNode *next;
    5. * };
    6. */
    7. class Solution {
    8. public:
    9. /**
    10. *
    11. * @param head ListNode类
    12. * @param m int整型
    13. * @param n int整型
    14. * @return ListNode类
    15. */
    16. ListNode*temp=nullptr;
    17. ListNode* reverseBetween(ListNode* head, int m, int n) {
    18. // write code here
    19. if(m==1)
    20. {
    21. return ReversN(head, n);
    22. }
    23. ListNode*node=reverseBetween(head->next, m-1, n-1);
    24. head->next=node;
    25. return head;
    26. }
    27. ListNode*ReversN(ListNode*head,int n)
    28. {
    29. if(n==1)
    30. {
    31. temp=head->next;//保存后面的节点
    32. return head;
    33. }
    34. ListNode*node=ReversN(head->next,n-1);
    35. //开始翻转
    36. head->next->next=head;
    37. head->next=temp;
    38. return node;
    39. }
    40. };

    五.奇偶链表

    1.对应letecode链接:

    328. 奇偶链表 - 力扣(LeetCode)

    2.题目描述:

     3.解题思路:

    1.根据节点编号的奇偶性,我们可以将奇数节点和偶数节点分离成奇数链表和偶数链表,然后将偶数链表连接在奇数链表之后,合并后的链表即为结果链表。

    2、从前往后遍历整个链表,遍历时维护四个指针:奇数链表头结点,奇数链表尾节点,偶数链表头结点,偶数链表尾节点,遍历时将位置编号是奇数的节点插在奇数链表尾节点后面,将位置编号是偶数的节点插在偶数链表尾节点后面。

    4.对应代码:

    1. class Solution {
    2. public:
    3. ListNode* oddEvenList(ListNode* head) {
    4. if (head == nullptr) {
    5. return nullptr;
    6. }
    7. ListNode* oddList = head;
    8. ListNode* EeveList = head->next;
    9. ListNode* oddcur = oddList;
    10. ListNode* evercur = EeveList;
    11. ListNode* cur = head;
    12. while (evercur && evercur->next) {//链表长度有可能是奇数或者是偶数
    13. oddcur->next = evercur->next;
    14. oddcur = oddcur->next;
    15. evercur->next = oddcur->next;
    16. evercur = evercur->next;
    17. }
    18. oddcur->next = EeveList;//链接
    19. return head;
    20. }
    21. };

     

  • 相关阅读:
    聊聊“死锁“
    为什么使用Hooks?
    [Ubuntu]ssh: unrecognized service
    harvard dataverse数据公开上传网站-数据库repository
    关于proTable的一些配置
    每天五分钟机器学习:如何解决过拟合问题?
    VHDL硬件描述语言(三)VHDL语言要素
    【Power BI】Power BI 入门指南:版本、下载和报表创建的步骤
    Nacos安装及在项目中的使用
    4、security之自定义数据源
  • 原文地址:https://blog.csdn.net/qq_56999918/article/details/125552973