算法—每K个一组反转链表

题目

给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
说明:

  1. 你需要自行定义链表结构,将输入的数据保存到你的链表中;
  2. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换;
  3. 你的算法只能使用常数的额外空间。
    输入描述:
    第一行输入是链表的值
    第二行输入是K的值,K是大于或等于1的整数

输入形式为:
1 2 3 4 5
2

输出描述:
当 k = 2 时,应当输出:
2 1 4 3 5

当 k = 3 时,应当输出:
3 2 1 4 5

当k=6时,应当输出:
1 2 3 4 5

分析

  1. 写一个函数reverseGroup(head, k),不断向后取k个结点进行翻转,并把前面翻转好的尾结点与新取的k个结点翻转后的头结点链接,如果链表不足k个结点,则不做翻转。

  2. 写一个reverseList(head, tail)进行局部翻转,设置两个指针head, tail 分别指向当前k个结点的头结点和尾结点,翻转之后,head和tail则指向当前k的结点的尾结点和头结点。

分析草图如下图所示:
分析草图

代码

import java.util.Scanner;

public class Main{
    //定义链表数据结构
    static class ListNode{
    public int val;
    public ListNode next=null;
    public ListNode(int val){
            this.val=val;
        }
    }
    public static ListNode reverseGroup(ListNode head, int k){
        //先判断链表和k的合法性
        if(head == null || head.next == null || k <= 1){
            return head;
        }
        //找出当前链表的第一组k个结点的头结点和尾节点
        int i = 1;
        ListNode tail = head;
        ListNode nextKhead = null;
        while(i < k){
            tail = tail.next;
            i++;
            //如果当前组不足k个,则不对其做反转
            if(tail == null){
                return head;
            }
        }
        nextKhead = tail.next; //nextKhead为下一组的头结点
        reverseList(head, tail);  //反转后,新的链表的头结点即是tail,尾结点则是head
        head.next = reverseGroup(nextKhead, k);
        return tail;
    }
    public static ListNode reverseList(ListNode head, ListNode tail){
        //链表反转,注意head指针是不能变的,因为它在该方法结束后,要作为当前链表的尾结点指针
        ListNode pre = head;
        ListNode node = pre.next; //node为当前结点
        pre.next = null;
        ListNode nodeNext = null;
        while(pre != tail){
            nodeNext = node.next;  //记录当前结点的下一个结点
            node.next = pre;
            pre = node;
            node = nodeNext;
        }
        return pre;
    }
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        String str=sc.nextLine(); //获取第一行的输入
        String stringArr[]= str.split(" ");
        int len = stringArr.length;
        int arr[] = new int[len];
        for(int count=0; count<len; count++){
            arr[count] = Integer.parseInt(stringArr[count]);
        }
        int k=sc.nextInt();  //获取第二行的输入k
        ListNode head=new ListNode(arr[0]);  //设置链表头节点
        ListNode p=head;
        for(int i=1;i<arr.length;i++){  //将剩下的数据加入链表
            ListNode q=new ListNode(arr[i]);
            p.next=q;
            p=q;
        }
        sc.close();
        ListNode p1 = reverseGroup(head, k); //每k个一组反转链表
        //输出链表
        while(p1 != null){
            System.out.printf("%d ", p1.val);
            p1 = p1.next;
        }
    }
}

运行结果

运行结果

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读