持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
说明:
- 需要自行定义链表结构,将输入的数据保存到你的链表中;
- 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换
- 算法只能使用常数的额外空间。
示例:
输入:
1 2 3 4 5
2
输出:
2 1 4 3 5
3、解题思路
递归实现
这应该是最容易想到的一个解题思路了。
假定K = 2,那么我们需要:
- 1、选定前两个节点;
- 2、将前两个节点作为一个链表进行反转;
- 3、将剩下的链表看作一个新的链表,重复步骤1;
实现代码:
package com.huayi.middleinterface.config;
import java.util.*;
public class ReverseListNode{
static class ListNode{
int currVal;
ListNode next = null;
ListNode(int val){
this.currVal = val;
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String[] inputStrArr = str.split(",");
ListNode head = new ListNode(-1);
ListNode rear = head;
//将输入数据都插入到链表中
for(String item : inputStrArr) {
ListNode newNode = new ListNode(Integer.parseInt(item));
rear.next = newNode;
rear = newNode;
}
int k = sc.nextInt();
//以K个节点为一组进行反转
ListNode newHead = reverseK(head.next, k);
//输出反转后的链表
ListNode curr = newHead;
while (curr != null) {
System.out.print(curr.currVal + ",");
curr = curr.next;
}
}
/**
* 以K个节点为一组,进行反转
* @param head
* @param k
* @return
*/
public static ListNode reverseK(ListNode head, int k){
//如果链表为 null 或者K < 1,无需反转
if(head == null || k <= 1) {
return head;
}
ListNode curr = head;
//判断链表长度是否 < K,同时找到反转的链表尾标
for(int i = 1; i < k && curr!=null; i++) {
curr = curr.next;
}
//链表长度不足K,直接返回
if(curr == null) {
return head;
}
//此时,cur就是下表为K的节点,我们需要保存第(K+1),然后将K+1 - end 当成一个新的链表,进行递归
ListNode nextList = curr.next;
curr.next = null;
//反转当前K个节点的链表
ListNode newHead = reverse(head);
// 递归处理后面链表
ListNode newNext = reverseK(nextList,k);
// 重新连接之前断开的链表
head.next = newNext;
// 返回反转后的新头节点
return newHead;
}
/**
* 反转链表
*/
public static ListNode reverse(ListNode head) {
//前一个节点的指针
ListNode pre = null;
//当前节点的指针
ListNode curr = head;
//下一个节点的指针
ListNode next = null;
//e.g. 1->2->3 ==> null<-1<-2<-3
while(curr != null) {
next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
return pre;
}
}
执行结果
时间复杂度
因为要进行K次循环,所以时间复杂度为 ,最好的情况就是循环1次 ,最差则是循环n次
空间复杂度
这里没有额外占用其他控件,为
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊