92.反轉連結串列2
阿新 • • 發佈:2020-09-09
反轉從位置 m 到 n 的連結串列。請使用一趟掃描完成反轉。
說明:
1 ≤m≤n≤ 連結串列長度。
示例:
輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL
自己的理解:需要反轉的連結串列的尾巴節點和它的next還有 頭結點和它的pre給找到,然後先斷開前驅和後繼,對需要反轉的部分進行反轉。然後連上前驅和後繼。
自己的程式碼:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * }*/ class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { ListNode HeadPre=new ListNode(-999); ListNode Head=new ListNode(-999); ListNode Final=new ListNode(-999); ListNode FinalNext=new ListNode(-999); //先找最後一個元素和最後一個元素之後的元素 Final=head;//找到最後一個元素 以及最後一個元素之後的元素 for(int i=0;i<n-1;i++) { Final=Final.next; } // System.out.println(Final.val); FinalNext=Final.next; Final.next=null; //找到第一個元素和前面的元素 if(m<2) { HeadPre.next=head; Head=HeadPre.next;//需要翻轉的頭結點 HeadPre.next=null;//先儲存這個翻轉之前的節點 } else{ HeadPre=head; for(int i=0;i<m-1-1;i++) { HeadPre=HeadPre.next; } // System.out.println(HeadPre.val); Head=HeadPre.next;//需要翻轉的頭結點 HeadPre.next=null;//先儲存這個翻轉之前的節點 } // System.out.println(head.val); ListNode prev = FinalNext; ListNode curr = Head; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } if (m<2) { head=prev; } else { HeadPre.next=prev; } return head; } }
專業的題解:
public ListNode reverseBetween(ListNode head, int m, int n) { ListNode res = new ListNode(0); res.next = head; ListNode node = res; //找到需要反轉的那一段的上一個節點。 for (int i = 1; i < m; i++) { node = node.next; } //node.next就是需要反轉的這段的起點。 ListNode nextHead = node.next; ListNode next = null; ListNode pre = null; //反轉m到n這一段 for (int i = m; i <= n; i++) { next = nextHead.next; nextHead.next = pre; pre = nextHead; nextHead = next; } //將反轉的起點的next指向next。 node.next.next = next; //需要反轉的那一段的上一個節點的next節點指向反轉後連結串列的頭結點 node.next = pre; return res.next; }