首页 > 试题广场 >

每K个一组反转链表

[编程题]每K个一组反转链表
  • 热度指数:9238 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

给出一个链表,每 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

输入

1 2 3 4 5
2

输出

2 1 4 3 5
class Node(object):
    def __init__(self,val):
        self.val = val 
        self.next = None
        
class Solution(object):
    def __init__(self,array):
        #初始化链表
        self.count = 0
        if not array:
            self.head = None
        temp = None
        for i in array:
            if not temp:
                self.head = Node(i)
                temp = self.head
            else:
                temp.next = Node(i)
                temp = temp.next
            self.count+=1
    def series(self,head):
        #把链表按照题目要求输出
        if not head:
            return None
        res = []
        temp = head
        while temp:
            res.append(temp.val)
            temp = temp.next
        print(' '.join(map(str,res)))
        
    def k_reverse(self,head,k):
        #链表按照每k节点反转一次,思路是每K个节点生成首尾的指针,然后按照首尾指针进行K个节点的翻转
        #每次翻转后的尾节点连向下一段节点,
        #其中下一段节点通过递归的方式来生成
        if head == None&nbs***bsp;head.next == None&nbs***bsp;k<=1:
            return head
        cur = head
        for i in range(k-1):
            cur = cur.next
            if cur == None:
                return head
        next = cur.next
        cur = self.reverse(head,cur)
        head.next = self.k_reverse(next,k)
        return cur
    
    def reverse(self,head,tail):
        #k_reverse的局部函数,用于给定首尾节点进行翻转
        if head == None&nbs***bsp;tail == None:
            return None
        cur = head
        pre = None
        post = None
        while cur != tail:
            post = cur.next
            cur.next = pre
            pre = cur
            cur = post 
        cur.next = pre
        return cur
def main():
    #先获取输入
    #把输入初始化为链表
    #让链表每K个翻转一次
    #输出链表
    in_list = map(int,input().split(" "))
    k = int(input())
    s = Solution(in_list)
    new_head = s.k_reverse(s.head,k)
    s.series(new_head)
main()
        

发表于 2019-12-05 16:59:21 回复(0)
import java.util.Scanner;

public class Main {
	static class ListNode{
		public int val;
		public ListNode next;
		public ListNode(int val) {
			this.val = val;
		}
	}
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String string = scanner.nextLine();
		int k = scanner.nextInt();
		String[] strings = string.split(" ");
		ListNode head = new ListNode(-1);
		ListNode tail = head;
		for(String str : strings) {
			ListNode node = new ListNode(Integer.valueOf(str));
			tail.next = node;
			tail = tail.next;
		}
		head = head.next;
		ListNode newHead = solution1(head, k);
		while(newHead != null) {
			if(newHead.next == null) System.out.println(Integer.valueOf(newHead.val));
			else System.out.print(Integer.valueOf(newHead.val) + " ");
			newHead = newHead.next;
		}
	}
	public static ListNode solution1(ListNode head, int k) {
		ListNode dummy = new ListNode(0);
		dummy.next = head;
		head = dummy;
		while(true) {
			head = solution2(head, k);
			if(head == null) break;
				
		}
		return dummy.next;
	}
	public static ListNode solution2(ListNode head, int k) {
		ListNode nk = head;
		for(int i = 0; i < k; i++) {
			if(nk == null) return null;
			nk = nk.next;
		}
		if(nk == null) return null;
		ListNode nkPlus = nk.next;
		ListNode n1 = head.next;
		ListNode pre = null;
		ListNode cur = n1;
		while(cur != nkPlus) {
			ListNode tmp = cur.next;
			cur.next = pre;
			pre = cur;
			cur = tmp;
		}
		head.next = nk;
		n1.next = nkPlus;
		return n1;
	}
}

发表于 2019-08-11 13:05:41 回复(1)

利用递归的方法最简单:

import java.util.*;
class ListNode{
    int val;
    ListNode next = null;
    ListNode(int val){
        this.val = val;
    }
}
public class reverseKlist{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()){
            String[] str = sc.nextLine().split(" ");
            int k = Integer.valueOf(sc.nextLine());
            ListNode pre = new ListNode(Integer.valueOf(str[0]));
            ListNode head = pre;
            for (int i=1;i<str.length;i++){
                ListNode node = new ListNode(Integer.valueOf(str[i]));
                pre.next = node;
                pre = node;
            }
            pre.next = null;
            head = reverse(head, k);
            while (head != null){
                System.out.print(head.val+" ");
                head = head.next;
            }
        }
    }
    public static ListNode reverse(ListNode head, int k){
        ListNode tmp = head;
        for (int i=1;i<k&&tmp!=null;i++)
            tmp = tmp.next;
        if (tmp == null) return head;
        ListNode Lhead = tmp.next;
        tmp.next = null;
        ListNode newHead = revK(head);
        ListNode newLHead = reverse(Lhead, k);
        head.next = newLHead;
        return newHead;
    }
    public static ListNode revK(ListNode head){
        ListNode tmp = null, pre = null;
        while (head != null){
            tmp = head.next;
            head.next = pre;
            pre = head;
            head = tmp;
        }
        return pre;
    }
}

发表于 2019-09-01 11:33:18 回复(0)
function LinkList() {
    let Node = function(val) {
        this.val = val;
        this.next = null;
    }
    let head = null;
    let length = 0;
    this.append = function(val) {
        let node = new Node(val);
        let cur
        if (head == null) {
            head = node
        } else {
            cur = head;
            while (cur.next) {
                cur = cur.next
            }
            cur.next = node
        }
        length++
    };
    this.getHead = function() {
        return head
    }
}
let arr = readline().split(' ');
let n = parseInt(readline())
let link = new LinkList()
for(let i = 0;i<arr.length;i++){
    link.append(arr[i])
}
let head = link.getHead();

let arr_temp = [], pNode = head;
while (pNode) {
    arr_temp.push(pNode.val)
    pNode = pNode.next
}
let res = []
while (arr_temp.length>0) {
    let test = arr_temp.splice(0, n)
    if(test.length == n ){
        test.reverse()
    }
    res.push(...test)
}
print(res.join(' '))

发表于 2019-08-25 10:38:05 回复(0)
#include<iostream>
#include<vector>

using namespace std;

typedef struct ListNode
{
    int data;
    ListNode * next;
}ListNode;

void Reverse(ListNode *q, int k);

int main()
{
    ListNode *phead = new ListNode();
    phead->next = nullptr;
    ListNode *q = nullptr, *p = phead;

    vector<int> vec;

    int num, s, k;

    while (cin >> num)
    {
        vec.push_back(num);
    }
    k = vec.back();

    for (int i = 0; i < vec.size() - 1; i++)
    {
        q = new ListNode();
        q->data = vec[i];
        q->next = nullptr;
        p->next = q;
        p = p->next;
    }


    s = (vec.size() - 1) / k;

    q = phead;
    while (s > 0)
    {
        s--;
        Reverse(q, k);
        for (int i = 0; i < k; i++)
        {
            q = q->next;
        }
    }

    q = phead;
    for (; q->next != nullptr; q = q->next)
    {
        cout << q->next->data << " ";
    }

    return 0;
}

void Reverse(ListNode *q, int k)
{
    ListNode *t, *pr = nullptr, *pf = nullptr;
    pf = q;
    if(k>2 || k == 1)
        for (int i = 0; i < k / 2; i++)
        {
            pr = pf->next;
            for (int j = 2 * i; j < k - 2; j++)
            {
                pr = pr->next;
            }
            t = pf->next->next;
            pf->next->next = pr->next->next;
            pr->next->next = t;
            t = pf->next;
            pf->next = pr->next;
            pr->next = t;
            pf = pf->next;
        }
    else
    {
        pr = pf->next;
        pf->next = pr->next;
        pr->next = pr->next->next;
        pf->next->next = pr;
    }
}
发表于 2020-07-05 16:35:01 回复(0)
/*
思路:写一个反转函数,每次都把相应长度的字符串进行翻转,反转可以用revese方法,不合题意
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String[] str = br.readLine().split(" ");
        int k = Integer.parseInt(br.readLine());
        if(str.length < k)
            for(int i = 0;i<str.length;i++){
                System.out.print(str[i] + " ");
                if(i==str.length-1)
                    System.out.println();
            }
        else{
            int n = str.length/k;
            for(int i = 0;i<n;i++){
                int left = 0 + i*k;
                int right = i*k + k -1;
                while(left < right){//反转
                    String temp = str[left];
                    str[left] = str[right];
                    str[right] = temp;
                    left++;right--;
                }
            }
            for(int i = 0;i<str.length;i++){
                System.out.print(str[i] + " ");
                if(i==str.length-1)
                    System.out.println();
            }
        }
    }
}
不合题意的解法
发表于 2020-05-22 15:36:43 回复(0)
小菜鸡的暴力思路
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        String[] s = str.split(" ");
        int k = sc.nextInt();

        //如果k== s.length,则整体倒序输出
        if (k == s.length){
            for (int i = s.length-1; i >= 0; i--) {
                System.out.print(s[i]+" ");
            }
        //如果k<s.length
        }else if (k < s.length){
            int index = 0;
            int len = s.length;
            //当剩余长度大于等于k时,反转输出
            while (len >= k){
                for (int i = index+k-1; i >= index; i--) {
                    System.out.print(s[i]+" ");
                }
                //index更新,长度剪短
                index += k;
                len -= k;
            }
            //剩余的长度小于K,则无法反转,要正序输出
            for (int i = index; i < s.length; i++) {
                System.out.print(s[i]+" ");
            }
        //如果k>s.length,不做反转    
        }else {
            for (int i = 0; i < s.length; i++) {
                System.out.print(s[i]+" ");
            }
        }

    }
}


发表于 2020-04-16 10:14:21 回复(0)
首先、我们可以算出输入的数组总长度、然后除以K,K的值有几种可能。
1、小于数组长度length
2、等于数组长度length
3、大于数组长度length
题目要求(调试得知):数组长度等于k时,逆序输出,如果大于K 就不逆序输出。
我们可以求出、n的值:拆分开了有了几组
                          m的值:剩下来还有几个不用逆序的
根据这些条件写出代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

class ListNode
{
    public String val;
    public ListNode(String str){
        this.val = str;
    }
    public ListNode next = null;
}


public class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int k = sc.nextInt();
        String[] s1 = s.split(" ");
        int length = s1.length;
        ListNode node = new ListNode(s1[0]);
        for (int i = 1; i < length; i++)
        {
            ListNode nextNode = new ListNode(s1[i]);
            node.next = nextNode;
        }

        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<String> list3 = new ArrayList<>();
        int m = length % k;
        int n = length / k;
        if(k <= 0)return;
        if(k == length){
            for (int i = 0; i < length; i++)
            {
                list3.add(s1[i]);
            }
            Collections.reverse(list3);
            for (int i = 0; i < list3.size(); i++)
            {
                System.out.print(list3.get(i) + " ");

            }
            return;
        }

        if(k > length){
            for (int i = 0; i < length; i++)
            {
                list3.add(s1[i]);
            }
            for (int i = 0; i < list3.size(); i++)
            {
                System.out.print(list3.get(i) + " ");

            }
            return;
        }

        for (int i = 0; i < n; i++)
        {
            for (int j = i * k; j < i * k + k; j++)
            {
                list1.add(s1[j]);
            }
            Collections.reverse(list1);
            list2.addAll(list1);
            list1.clear();
        }
        if(m != 0){
            for (int i = n * k; i < length; i++)
            {
                list2.add(s1[i]);
            }
        }

        for(int i = 0; i < list2.size(); i++){
            System.out.print(list2.get(i) + " ");
        }
    }
}
其实可以直接 对list进行操作、操作完之后直接输出就可以了

发表于 2020-01-06 11:23:16 回复(0)
import java.util.*;
class ListNode{
int val;
ListNode next;
public ListNode(int val){
this.val=val;
}
}
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
String []s=sc.nextLine().split(" ");
int [] nums=new int[s.length+1];
nums[0]=-1;
for(int i=0;i<s.length;i++){
nums[i+1]=Integer.parseInt(s[i]);
}
int k=sc.nextInt();
int times=s.length/k;
ListNode head=new ListNode(nums[0]);
ListNode res=head;
for(int now=1;now<=times;now++){
for(int j=now*k;j>=(now-1)*k+1;j--){
ListNode next=new ListNode(nums[j]);
head.next=next;
head=next;
}
}
if(s.length%k!=0){
for(int y=times*k+1;y<=s.length;y++){
ListNode next=new ListNode(nums[y]);
head.next=next;
head=next;
}
}
res=res.next;
while(res!=null){
System.out.print(res.val+" ");
res=res.next;
}
}
}
编辑于 2019-09-07 14:00:55 回复(0)
确定k有几组,然后循环,每组内部再循环,注意奇偶数,cishu = k//2,取左中位数
def reverse(array, left, right, k):
    cishu = k // 2
    while cishu > 0:
        array[left], array[right] = array[right], array[left]
        left += 1
        right -= 1
        cishu -= 1

array = list(map(int, input().split()))
k = int(input())
beishu = len(array) // k
left = 0
right = k-1
for i in range(beishu):
    reverse(array, left, right, k)
    left += k
    right += k

print(" ".join(str(i) for i in array))

发表于 2019-08-17 14:43:38 回复(4)
真恶心啊,对待测试用例不需要用循环,运行一次只需要输入一组数据。。。。
怪不得搞了半天不通过,注意不要用循环检测输入!!!!
import java.util.Scanner;

public class Main{
    static class ListNode{
        private int val;
        public ListNode next;
        public ListNode(int val){
            this.val=val;
        }
    }
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        //while(in.hasNextLine()){
            String[] nums=in.nextLine().split(" ");
            
            int k=in.nextInt();
            if(nums.length==0) {
                System.out.println();
                //continue;
            }

            if(nums.length==1) {
                System.out.println(nums[0]);
                //continue;
            }
            if(nums.length<2) return;
            ListNode head=new ListNode(0);
            ListNode last=head;
            for(String s:nums){
                last.next=new ListNode(Integer.parseInt(s));
                last=last.next;
            }
            if(k>1){
                reverse(head,k);
            }
            head=head.next;
            while(head.next!=null){
                System.out.print(head.val+" ");
                head=head.next;
            }
            System.out.println(head.val);
        //}
    }
    
    public static void reverse(ListNode head,int k){

        while(isK(head,k)){
            ListNode p=head.next;
            ListNode q=p.next;
            ListNode last=p;
            for(int i=0;i<k-1;i++){
                ListNode tmp=q;
                q=q.next;
                tmp.next=p;
                p=tmp;
            }
            head.next=p;
            last.next=q;
            head=last;
        }
        return;
    }
    
    public static boolean isK(ListNode head,int k){
        for(int i=0;i<k;i++){
            head=head.next;
            if(head==null) return false;
        }
        return true;
    }
}

发表于 2019-07-23 21:53:04 回复(2)
方法一:反正都要翻转,链表操作麻烦还不如翻转字符串先,再构造一个链表。就是使用栈翻转字符串
import java.util.*;
class ListNode{
    int val;
    ListNode next = null;
    ListNode(int val){
        this.val=val;
    }
}
public class Main{
    public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
        String[] str= sc.nextLine().split(" ");
        int k=sc.nextInt();
        int n =str.length;
        Stack<String> ss = new Stack<String>();//以下就是翻转啦
        for(int j=0;j+k<=n;j+=k){
            for(int i=j;i<j+k;i++) ss.push(str[i]);
            for(int i=j;i<j+k;i++) str[i]=ss.pop();
        }

        ListNode list = create(str,n); 
        for(int i=0;i<n;i++){
        	System.out.print(list.val+" ");
            list=list.next;
        }
    }
    public static ListNode create(String[] str,int n){
        ListNode preList=new ListNode(0);
        ListNode list=preList;
        for(int i=0;i<n;i++){
            list.next=new ListNode(Integer.parseInt(str[i]));
            list=list.next; 
        }
        return preList.next;
    }
}


编辑于 2019-08-30 19:28:50 回复(1)
每k个节点进行一次反转,用两个指针记录k个区间的首尾节点,写一个reverse函数反转该局部内的节点指向,接着继续向后走,不停的取k个进行反转,如果不够k个就返回。已AC
import java.util.Scanner;

public class Main {
    //定义Node节点
    static class ListNode {
        public int val;
        public ListNode next = null;

        public ListNode(int val) {
            this.val = val;
        }
    }

    public static void main(String[] args) {
        //1.获取输入信息
        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        int k = scanner.nextInt();
        String[] strings = string.split(" ");
        //2.创建头结点
        ListNode head = new ListNode(0);
        ListNode tail = head;
        //3.将输入的字符串变为链表节点
        for (String str : strings) {
            ListNode newNode = new ListNode(Integer.valueOf(str));
            tail.next = newNode;
            tail = tail.next;
        }
        head = head.next;
        //每k个反转链表
        ListNode node = reverseGroup(head, k);
        while(node!=null){
            System.out.print(node.val+" ");
            node = node.next;
        }
    }

    //不停地取k个进行翻转,如果不够k个,就直接返回,结束
    public static ListNode reverseGroup(ListNode head, int k) {
        if (head == null || head.next == null || k <= 1)
            return head;
        ListNode currentNode = head;
        //获取k个元素的首尾节点
        for (int count = 1; count < k; count++) {
            currentNode = currentNode.next;
            //不够K个则返回
            if(currentNode==null)
                return head;
        }
        ListNode next = currentNode.next;
        //对局部链表进行反转
        reverse(head,currentNode);
        head.next=reverseGroup(next,k);
        return currentNode;
    }

    //写一个头尾节点反转的局部函数
    public static ListNode reverse(ListNode head, ListNode tail) {
        if (head == null || head.next == null)
            return head;
        ListNode pre = null;
        ListNode next = null;
        while (pre != tail) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

}


发表于 2019-09-10 16:39:15 回复(2)
// 分段翻转
#include "iostream"
#include "vector"
using namespace std;

struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int x):val(x),next(nullptr){}
};

ListNode* creatList(vector<int> myVec)
{
    ListNode* pHead=new ListNode(myVec[0]);
    ListNode* prev = pHead;
    for(int i=1;i<myVec.size()-1;i++)
    {
        pHead->next = new ListNode(myVec[i]);
        pHead=pHead->next;
    }
    return prev;
}

ListNode* reverseList(ListNode* pHead,int k)
{
    ListNode* right = pHead;
    ListNode* left = pHead;
    ListNode* prev = pHead;
    for(int i=0;i<k;i++)
    {
        if(right!=nullptr)
            right = right->next;
        else
            return left;
    }
    ListNode* head = left;
    while(left!=right)
    {
        ListNode* pNext = left->next;
        left ->next = prev;
        prev = left;
        left = pNext;
    }
    head->next = reverseList(right,k);
    return prev;
    
}

int main()
{
    vector<int> myVec;
    int temp=0;
    while(cin>>temp)
        myVec.push_back(temp);
    int k=myVec[myVec.size()-1];
    ListNode* pHead = creatList(myVec);
    pHead = reverseList(pHead, k);
    while(pHead!=nullptr)
    {
        cout<<pHead->val<<" ";
        pHead=pHead->next;
    }
        
    return 0;
}



发表于 2019-08-16 20:52:11 回复(8)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    int k,n=0;
    cin>>k;
    vector<int>num;
    for(int i=0;i<s.size();i++)
    {
        if(isdigit(s[i]))
            n=n*10+s[i]-'0';
        else
        {
            num.push_back(n);
            n=0;
        }
    }
    num.push_back(n);
    for(int i=0;i<num.size()/k;i++)
        reverse(num.begin()+i*k,num.begin()+i*k+k);
    for(int i=0;i<num.size();i++)
        cout<<num[i]<<" ";
    cout<<endl;
    return 0;
}

发表于 2019-08-14 23:17:56 回复(0)
比较简洁
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
    var a = (await readline()).split(" ").map(Number);
    var k = parseInt(await readline());
    if(k>a.length||k<2){
        console.log(a.join(' '))
        return 
    }
    for (let i = 0; i < a.length; i++) {
        if (i % k == 0&&i+k<=a.length) {
            var tmp=a.splice(i,k)
            a.splice(i,0,...tmp.reverse())
        }
    }
    console.log(a.join(' '));
})();

发表于 2024-02-13 09:45:20 回复(0)
package main

import (
    "fmt"
)

func main() {
    var x int
    arr:=[]int{}
    for{
        _,ok:=fmt.Scan(&x)
        if ok!=nil{
            break
        }
        arr=append(arr,x)
    }
    k:=arr[len(arr)-1]
    arr=arr[:len(arr)-1]
    for l,r:=0,k-1;r<len(arr);l,r=l+k,r+k{
        arr=reverse(l,r,arr)
    }
    for _,x:=range arr{
        fmt.Printf("%v ",x)
    }
}

func reverse(i,j int,arr []int)[]int{
    for i<j{
        arr[i],arr[j]=arr[j],arr[i]
        i++
        j--
    }
    return arr
}

发表于 2023-03-18 10:20:48 回复(0)
每k个一组进行反转,需要将上一个k组的头指针转换为尾指针时,需要将next指针指向下一组的头指针。需要额外常量数量的指针纪录头尾指针。对指针进行反转。注意最后数量如果小于k不进行反转,所以需要先遍历链表确定链表剩余长度是否大于k。
发表于 2023-03-09 08:19:50 回复(0)
function ListNode(x){
    this.next = null;
    this.val = x;
}

let list = new ListNode();
let head = list;
let data = readline().split(' ').map(value => parseInt(value));
let k = parseInt(readline());
for(let i = 0;i<data.length;i++){
    head.next = new ListNode(data[i]);
    head = head.next;
}
let head1 = list.next;
var reverseLink = function(head,k){
    let prev = null,cur = head;
    let p = head;
    let i = 0;
    while(i<k){
        if(p == null){
            return head;
        }
        p = p.next;
        i++;
    }
    for(let i = 0;i<k;i++){
        let next = cur.next;
        cur.next = prev;
        prev = cur;
        cur = next;
    }
    head.next = reverseLink(cur,k);
    return prev;
}
let result = reverseLink(head1,k);
let res = []
while(result){
    res.push(result.val);
    result = result.next;
}
console.log(res.join(' '));

发表于 2022-06-20 16:01:02 回复(0)
不仅仅
发表于 2022-02-22 13:17:19 回复(0)