链表问题-不开辟新空间

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-
 */
View Code

 

posted on 2019-08-25 22:55  周健康  阅读(432)  评论(0编辑  收藏  举报

导航