leetcode--206. 反转链表

题目:

反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

思路一:

反转指针,设置三个指针,分别指向前中后,依次将指针反转,并将head指向原来的尾部
要注意的特殊情况: [],[1]

  public ListNode reverseList(ListNode head) {
     ListNode pre = head;    //前一个指针
      ListNode nex;           //后一个指针
      if(head == null)        //处理输入空链表的情况
          return head;
      else
         nex = head.next;
      pre.next = null;        //将原来的头节点变为尾节点,将他的next置空
      while(nex != null){
          head = nex;
          nex = head.next;    //移动指针
          head.next = pre;    //更改结点指针的指向,将指向后面的指针变为指向前面
          pre = head;
      }
      return head;
  }

可参考leetcode大佬评论

  public static ListNode reverseListIterative(ListNode head) {
      ListNode prev = null; //前指针节点
      ListNode curr = head; //当前指针节点
      //每次循环,都将当前节点指向它前面的节点,然后当前节点和前节点后移
      while (curr != null) {
          ListNode nextTemp = curr.next; //临时节点,暂存当前节点的下一节点,用于后移
          curr.next = prev; //将当前节点指向它前面的节点
          prev = curr; //前指针后移
          curr = nextTemp; //当前指针后移
      }
      return prev;
  }
  转自: https://leetcode-cn.com/problems/reverse-linked-list/comments/
思路二:

前插法创建一个头指针,依次遍历原来的链表,将原来的结点逐个插入到新的链表中
此种方法其实并没有new新的结点,只是将原来的结点,在新的指针上面排了一个序,通过前插法,实现新的序列是原来的逆序

  public ListNode reverseList(ListNode head) {
     ListNode new_head = null;   //建立新指针
      while(head != null){
          ListNode tmp = head;    //建立临时结点保存head
          head = head.next;       //head后移
          tmp.next = new_head;    //将tmp前插到新的链表中
          new_head = tmp;
      }
  }
  return new_head;
思路三:

递归方法,直接递归到链表的尾部,将p指向尾部,然后用head进行处理,最后return p到第一层

public ListNode reverseList(ListNode head) {
 if(head==null || head.next==null) return head;  //处理[],[1]两种情况,将head指针定位在原来链表尾结点的前一个结点,然后进行处理
     ListNode p = reverseList(head.next);    //将p定位在原来链表的尾部,不需要对p进行其他操作
     head.next.next = head;  //  反转链表指针
     head.next = null;
     return p;
}
92:反转链表 II

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

  public ListNode reverseBetween(ListNode head, int m, int n) {
      if(m==n) return head;   //处理空链表
      ListNode res = new ListNode(0); //新建一个头结点是为了应对m=1的情况
      res.next = head;
      ListNode pre = res;
      for(int i=1;i<m;i++)
          pre = pre.next; //将pre结点指向,第m结点的前一个结点,也就是开始翻转的前一个结点
      head = pre.next;    //head指向开始翻转的结点
      for(int j=m;j<n;j++){
          ListNode nex = head.next;   //临时结点,指向head的下一个结点
          head.next = nex.next;       //延长head的next结点,将他指向nex后一个结点,以便于循环结束,让要翻转的部分与不反转的后一部分连接上
          nex.next = pre.next;        //实现head与nex的翻转
          pre.next = nex;             //延长pre,以便于循环结束,将pre指向要反转的最后一个节点
      }
      return res.next;
  }
posted @ 2020-03-21 12:32  文戌  阅读(126)  评论(0编辑  收藏  举报