相关推荐recommended
算法leetcode|92. 反转链表 II(rust重拳出击)
作者:mmseoamin日期:2023-12-13

文章目录

  • 92. 反转链表 II:
    • 样例 1:
    • 样例 2:
    • 提示:
    • 进阶:
    • 分析:
    • 题解:
      • rust:
      • go:
      • c++:
      • python:
      • java:

        92. 反转链表 II:

        给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

        样例 1:

        算法leetcode|92. 反转链表 II(rust重拳出击),第1张

        输入:
        	
        	head = [1,2,3,4,5], left = 2, right = 4
        	
        输出:
        	
        	[1,4,3,2,5]
        

        样例 2:

        输入:
        	
        	head = [5], left = 1, right = 1
        	
        输出:
        	
        	[5]
        

        提示:

        • 链表中节点数目为 n
        • 1 <= n <= 500
        • -500 <= Node.val <= 500
        • 1 <= left <= right <= n

          进阶:

          • 你可以使用一趟扫描完成反转吗?
          • 将链表分成3部分,即前面不需要反转的部分,中间需要反转的部分,后面不需要反转的部分。
          • 单向链表只能从一个方向遍历,并且不能随机访问,所以我们只能按照顺序处理,这里就不能有什么好的技巧了。
          • 先处理前面不需要反转的部分,直接遍历跳过即可,这里由于没法随机访问,所以只能按顺序遍历。
          • 接下来处理中间需要反转的部分,想象一下入栈,遍历一个节点就放到头(中间需要遍历部分的头),依次遍历处理,就完成了反转。
          • 最后处理后面不需要遍历的部分,其实这部分不需要做什么处理,所以不需要继续遍历,但是要当心将链表接起来。
          • 这里不得不说由于rust的所有权问题,同一时间只能有一个可修改指针,可能是二当家水平太菜,处理链表有点啰嗦。

            分析:

            • 面对这道算法题目,二当家的再次陷入了沉思。

              题解:

              rust:

              // Definition for singly-linked list.
              // #[derive(PartialEq, Eq, Clone, Debug)]
              // pub struct ListNode {
              //   pub val: i32,
              //   pub next: Option>
              // }
              //
              // impl ListNode {
              //   #[inline]
              //   fn new(val: i32) -> Self {
              //     ListNode {
              //       next: None,
              //       val
              //     }
              //   }
              // }
              impl Solution {
                  pub fn reverse_between(head: Option>, left: i32, right: i32) -> Option> {
                      // 来个哑节点方便处理头节点在反转范围内的情况
                      let mut dummy = Option::Some(Box::new(ListNode::new(0)));
                      dummy.as_mut().unwrap().next = head;
                      // 前面不需要反转部分的尾
                      let mut pre = dummy.as_mut().unwrap();
                      // 跳过前面不需要翻转的部分
                      for _ in 0..left - 1 {
                          pre = pre.next.as_mut().unwrap();
                      }
                      // 中间需要反转的部分(同时打断前面不需要反转部分和中间需要反转部分的链接)
                      let mut cur = pre.next.take();
                      // 进行反转
                      for _ in 0..right - left {
                          let mut next = cur.as_mut().unwrap().next.take();
                          cur.as_mut().unwrap().next = next.as_mut().unwrap().next.take();
                          next.as_mut().unwrap().next = pre.next.take();
                          pre.next = next;
                      }
                      // 重新接上
                      while pre.next.is_some() {
                          pre = pre.next.as_mut().unwrap();
                      }
                      pre.next = cur;
                      return dummy.unwrap().next;
                  }
              }
              

              go:

              /**
               * Definition for singly-linked list.
               * type ListNode struct {
               *     Val int
               *     Next *ListNode
               * }
               */
              func reverseBetween(head *ListNode, left int, right int) *ListNode {
                  // 来个哑节点方便处理头节点在反转范围内的情况
              	dummy := &ListNode{Val: 0, Next: head}
              	pre := dummy
              	for i := 0; i < left-1; i++ {
              		pre = pre.Next
              	}
              	cur := pre.Next
              	for i := 0; i < right-left; i++ {
              		next := cur.Next
              		cur.Next = next.Next
              		next.Next = pre.Next
              		pre.Next = next
              	}
              	return dummy.Next
              }
              

              c++:

              /**
               * Definition for singly-linked list.
               * struct ListNode {
               *     int val;
               *     ListNode *next;
               *     ListNode() : val(0), next(nullptr) {}
               *     ListNode(int x) : val(x), next(nullptr) {}
               *     ListNode(int x, ListNode *next) : val(x), next(next) {}
               * };
               */
              class Solution {
              public:
                  ListNode* reverseBetween(ListNode* head, int left, int right) {
                      // 来个哑节点方便处理头节点在反转范围内的情况
                      ListNode *dummy = new ListNode(0);
                      dummy->next = head;
                      ListNode *pre = dummy;
                      for (int i = 0; i < left - 1; ++i) {
                          pre = pre->next;
                      }
                      ListNode *cur = pre->next;
                      ListNode *next;
                      for (int i = 0; i < right - left; ++i) {
                          next = cur->next;
                          cur->next = next->next;
                          next->next = pre->next;
                          pre->next = next;
                      }
                      return dummy->next;
                  }
              };
              

              python:

              # Definition for singly-linked list.
              # class ListNode:
              #     def __init__(self, val=0, next=None):
              #         self.val = val
              #         self.next = next
              class Solution:
                  def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
                      # 来个哑节点方便处理头节点在反转范围内的情况
                      dummy = ListNode(0)
                      dummy.next = head
                      pre = dummy
                      for _ in range(left - 1):
                          pre = pre.next
                      cur = pre.next
                      for _ in range(right - left):
                          next = cur.next
                          cur.next = next.next
                          next.next = pre.next
                          pre.next = next
                      return dummy.next
              

              java:

              /**
               * Definition for singly-linked list.
               * public class ListNode {
               *     int val;
               *     ListNode next;
               *     ListNode() {}
               *     ListNode(int val) { this.val = val; }
               *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
               * }
               */
              class Solution {
                  public ListNode reverseBetween(ListNode head, int left, int right) {
                      // 来个哑节点方便处理头节点在反转范围内的情况
                      ListNode dummy = new ListNode(0);
                      dummy.next = head;
                      ListNode pre = dummy;
                      for (int i = 0; i < left - 1; i++) {
                          pre = pre.next;
                      }
                      ListNode cur = pre.next;
                      ListNode next;
                      for (int i = 0; i < right - left; i++) {
                          next = cur.next;
                          cur.next = next.next;
                          next.next = pre.next;
                          pre.next = next;
                      }
                      return dummy.next;
                  }
              }
              

              非常感谢你阅读本文~

              欢迎【点赞】【收藏】【评论】三连走一波~

              放弃不难,但坚持一定很酷~

              希望我们大家都能每天进步一点点~

              本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~