從頭逆序java
圖解步驟this
備份head.next(原下一節點),修改head.next指向新頭,移動修改兩鏈表的頭指針(新指向新的節點(原頭節點),原再指向下一節點[備份點])spa
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseList(ListNode head) { ListNode curr=head; ListNode newHead=null; while(curr!=null){ //備份next ListNode bak=curr.next; //修改next指向,既將head與newHead鏈接 curr.next=newHead; //移動head和newHead newHead=curr; curr=bak; } return newHead; } }
public ListNode reverseList(ListNode head) { //遞歸到最下一層得到末尾節點 if (head == null || head.next == null) return head; //每次遞歸完成後head都會往前移位 ListNode p = reverseList(head.next); //head.next既當前節點(5),將其下一節點指向前一節點(4) head.next.next = head; //將前一節點(4)指向null head.next = null; //返回固定節點(5) return p; }
部分逆序指針
圖解步驟code
迭代法blog
/** * 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) { //須要逆置的節點數 int len=n-m+1; //備份原始頭節點 ListNode result=head; ListNode pre_head=null; //找到開始逆置節點 for(int k=1;k<m;k++){ //找到逆置節點前節點 pre_head=head; head=head.next; } //設置new_head ListNode new_head=head; //備份更改後的尾節點 ListNode modify_tail=head; //逆置begin for(int num=0;num<len;num++){ //備份head的下節點 ListNode bak_next=head.next; //下節點指向新頭 head.next=new_head; //新頭向前移 new_head=head; //原頭後移 head=bak_next; } //將後置節點連上 modify_tail.next=head; //將前驅節點連上 if(pre_head!=null) pre_head.next=new_head; else result=new_head; //若從頭節點逆置,返回值應該爲新頭節點 //返回原始頭 return result; } }
遞歸換值法遞歸
class Solution { private boolean stop; private ListNode left; public ListNode reverseBetween(ListNode head,int m,int n){ this.left=head; this.stop=false; this.recurseAndReverse(head,m,n); //最上層的仍是head節點,直接返回head return head; } /** *function:遞歸到最下層並進行一次交換 *tips:每次的最右節點都是回溯的 */ public void recurseAndReverse(ListNode right,int m,int n){ //若是右到底,結束遞歸 if(n==1) return; //爲了找到右節點 right=right.next; //爲了找到左節點 if(m>1){ this.left=this.left.next; } //遞歸得到最左及最右節點 recurseAndReverse(right,m-1,n-1); //遞歸後的每一次都從這裏開始交換 //定義暫停條件 if(this.left==right||this.left==right.next){ this.stop=true; } if(!this.stop){ //交換值 int temp=this.left.val; this.left.val=right.val; right.val=temp; //左就向右移動一位 //右經過回溯左移一位 this.left=this.left.next; } } }