链表问题-不开辟新空间
1,将单向链表【逆向翻转】
方法1:直接使用索引进行,有点类型冒泡排序,但是又不同,时间复杂度O(n^2)。
0-1-2-3-4
1-0-2-3-4
1-2-0-3-4
1-2-3-0-4
1-2-3-4-0
将head转到tail
再次将新head转到倒数第二个
方法2:直接使用递归进行,指向与尾部索引更改
package com.cnblogs.mufasa.demo1; public class Node { public int value; public Node next; public Node(int value){ this.value=value; } public void add(int value){ Node pre=this; while (pre.next!=null){ pre=pre.next; } pre.next=new Node(value); } public static Node reverseList(Node head){//1,利用Node索引解决问题【完成】 Node next=null; Node pre=null; while (head!=null){ next=head.next; head.next = pre; pre=head; head=next; } return pre; } public static Node reverseList2(Node head){//2,利用递归解决问题【完成】 if (head == null || head.next == null) { return head;//节点为空或单节点 } //递归反转子lian链表 Node newList = reverseList2(head.next); //第三张图,原本:1-2-3-4-->2-1-nul 34 head.next.next = head; head.next = null; return newList; } } class client{ public static void main(String[] args) { Node root=new Node(1); for(int i=2;i<10;i++){ root.add(i); } Node reRoot=Node.reverseList(root); Node reRoot1=Node.reverseList2(root); } }
2,拓展【部分翻转】【结合第二种方法直接在指定节点进行拆分、合并2019-09-10】
给定一个单链表的头节点 head,实现一个调整单链表的函数,使得每K个节点之间为一组进行逆序,并且从链表的尾部开始组起,头部剩余节点数量不够一组的不需要逆序。(不能使用队列或者栈作为辅助)
先来个简单的算法【从头开始每隔3个进行翻转】:【递归调用】
public Node reverseForwordSingle(Node head,int k){//正序特定长度翻转 if(head==null){ return null; }else if(head.next==null){ return head; } Node pre=null; Node next=null; int counter=0; while (head!=null &&counter<k){ next=head.next; head.next=pre; pre=head; head=next; counter+=1; } head=pre; while (pre.next!=null){ pre=pre.next; } pre.next=reverseForwordSingle(next,k); return head; }
后面的逆序翻转,有使用顺序翻转的方法:
public Node reverseBackwordSingle(Node head,int k){//逆序特定长度翻转 if(head==null){ return null; }else if(head.next==null){ return head; } int counter=1;//对数据进行计数 Node pre=head; while (pre.next!=null){ pre=pre.next; counter+=1; } if(counter%k==0){//刚好整除 return reverseForwordSingle(head,k); }else if(counter%k==1) {//前面需要进行 有1个余数 pre = head; }else { pre = head; int counter1=1; while (counter1<counter%k){ counter1+=1; pre=pre.next; if(pre==null){ return head; } } } pre.next=reverseForwordSingle(pre.next,k); return head; }
package com.cnblogs.mufasa.demo2; public class Node { public int value; public Node next; public Node(int value){ this.value=value; } public void add(int value){//添加节点 Node pre=this; while (pre.next!=null){ pre=pre.next; } pre.next=new Node(value); } public static String traverse(Node root){ if(root==null){ return "null"; }else if(root.next==null){ return root.value+"-"; } String str=root.value+"-"; while (root.next!=null){ root=root.next; str+=root.value+"-"; } return str; } public Node reverseForwordSingle(Node head,int k){//正序特定长度翻转 if(head==null){ return null; }else if(head.next==null){ return head; } Node pre=null; Node next=null; int counter=0; while (head!=null &&counter<k){ next=head.next; head.next=pre; pre=head; head=next; counter+=1; } head=pre; while (pre.next!=null){ pre=pre.next; } pre.next=reverseForwordSingle(next,k); return head; } public Node reverseBackwordSingle(Node head,int k){//逆序特定长度翻转 if(head==null){ return null; }else if(head.next==null){ return head; } int counter=1;//对数据进行计数 Node pre=head; while (pre.next!=null){ pre=pre.next; counter+=1; } if(counter%k==0){//刚好整除 return reverseForwordSingle(head,k); }else if(counter%k==1) {//前面需要进行 有1个余数 pre = head; }else { pre = head; int counter1=1; while (counter1<counter%k){ counter1+=1; pre=pre.next; if(pre==null){ return head; } } } pre.next=reverseForwordSingle(pre.next,k); return head; } } class Client{ public static void main(String[] args) { Node root=new Node(1); for(int i=2;i<10;i++){ root.add(i); } System.out.println(root.traverse(root)); // Node reRoot= root.reverseForwordSingle(root,3); // System.out.println(root.traverse(reRoot)); Node reRoot1= root.reverseBackwordSingle(root,5); System.out.println(root.traverse(reRoot1)); } } /* 1-2-3-4-5-6-7-8-9- 1-2-3-4-9-8-7-6-5- */
探究未知是最大乐趣