栈和队列----将单链表的每K个节点之间逆序

将单链表的每K个节点之间逆序

  

  给定一个单链表的头节点head,实现一个调整链表的函数,使得每K 个节点之间逆序,如果最后剩下不够K 个节点,则不调整最后几个。

  例如:

  链表:1—>2—>3—>4—>5—>6—>7—>8—>null,k=3。

  调整好后:3—>2—>1—>6—>5—>4—>7—>8—>null,其中7、8不调整,因为不够一组。

  

  【解析】

  1. 首先从左到右遍历链表,如果栈的大小不等于k ,则不断的入栈

  2. 当栈的大小等于k 时,不断的出栈,并重新连接这些节点

  3. 最后应该返回 newHead

package com.test;

import com.test.ListNode;

import java.util.Stack;

/**
 * Created by Demrystv.
 */
public class ReverseListNodeEveryK {

    /**
     * 使用栈的数据结构,时间复杂度是O(N),空间复杂度是O(N)
     */
    public ListNode reverseListNodeEveryK(ListNode head, int k){
        if (k < 2){
            return null;
        }
        Stack<ListNode> stack = new Stack<ListNode>();
        ListNode newHead = head;
        ListNode cur = head;
        ListNode pre = null;
        ListNode next = null;
        while (cur != null){
            next = cur.next;
            stack.push(cur);
            if (stack.size() == k){
                pre = resign1(stack, pre, next);
                // 举例说明可得证,例如k = 3
                // 如果是1 2 ,那么不需要反转,程序也执行不到这个if里面来,所以返回的是 头节点
                // 如果是1 2 3 4 ,当执行到3的时候,到了这个if里面,这时满足newHead==head,所以newHead就是3,符合反转后  3 2 1 4
                // 如果是1 2 3 4 5 6 7,执行到3,newHead是3,执行到6,不满足newHead==head,所以newHead就是newHead,就是3,符合 3 2 1 6 5 4 7
                // 真是巧妙呀!!!
                newHead = newHead == head ? cur : newHead;
            }
            cur = next;
        }
        return newHead;
    }

    private ListNode resign1(Stack<ListNode> stack, ListNode left, ListNode right){
        ListNode cur = stack.pop();
        if (left != null){
            left.next = cur;
        }
        ListNode next = null;
        while (!stack.isEmpty()){
            next = stack.pop();
            cur.next = next;
            cur = next;
        }
        // 实际传入的这个right参数,是下一个K 范围内的第一个节点,不属于这个k 范围内。
        // 确保与后面的相连
        cur.next = right;
        // 实际返回的这个cur 是这个K范围内的最后一个节点,即下一个k 的上一个节点,即pre 的意思
        return cur;
    }
}

原文地址:https://www.cnblogs.com/Demrystv/p/9339021.html

时间: 2024-08-28 07:49:40

栈和队列----将单链表的每K个节点之间逆序的相关文章

栈,队列,单链表,双向链表

1. 定义头文件 实现栈方法的定义,注意这里用到了全局的静态数组,可以通过这种方式保护数据. main.c,实现存储 队列,创建头文件queue.h 创建queue.c 实现main函数 单链表 在定义头文件的时候,最好使用: #ifndef 变量A #define变量A 函数声明和结构声明等声明 #endif 通过上面的这种方式可以避免重复调用头文件时候产生的负面影响. 定义头文件link.h:(注意加上extern) 定义link.c 编写main.c 4.双向链表 创建link.h头文件

栈、队列、单链表

栈: <span style="color:#000000;">#define MAX_SIZE 100//队列的最大长度 //-------------------------栈----------------------- int top=0;//栈顶变量 void add(char st[],char intput){ //入栈函数 st[top]=intput; top++; } void pop(char st[]){ //出栈函数 top--; st[top]=

单链表倒数第K个节点的查找和显示

1.使用一个固定长度队列装链表段,当遍历到链表根时,返回队列头元素. class Node{ int value; Node next; public Node(int value){ this.value=value; } } public class Danlianbiao { public static void main(String[] args) { Node node=new Node(1); Node node2=node.next=new Node(2); Node node3

C++单链表(下标n到下标m的逆序)

#include <iostream> using namespace std; template<typename T> struct Node { T data; Node *next; Node():next(NULL){} }; template<typename T> class List { public: List() { head = new Node<T>(); } void Insert(T x) { Node<T> *s =

删除单链表中第i个节点

单链表的删除操作是将单链表的第i个节点删去.具体步骤如下: (1)找到节点ai-1的存储位置p,因为在单链表中节点ai的存储地址是在其直接前趋节点ai-1的指针域next中: (2)令p->next指向ai的直接后继节点ai+1: (3)释放节点ai的空间: #include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; } NODE; // 尾插法创建单链表(

【剑指offer】链表倒数第k个节点

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25662121 在Cracking the Code Interview上做过了一次,这次在九度OJ上测试,AC. 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为两个整数n和k(0<=n<=1000, 0<=k<=1000):n代表将要输入的链表元素的

单链表的经典操作,查找链表倒数第k个节点,判断链表是否存在环,求环节点

#include<stdio.h>#include<stdlib.h> typedef struct date_list{    int data;    struct date_list* next;}mylist; mylist* creatlist(int x,mylist* p)        //用一个元素创建链表{    if(NULL == p)                         //链表创建必须判空    {        p = malloc(siz

Java-找出两个单链表的首个公共节点

单链表中的简单算法 /** * 得到两个单链表的公共结点 * 先求出两个链表的长度,并求出二者的差值dif,两个指针分别指向链表头部,让指向长的链表的指针先向链表尾部移动dif步. * 最后一起一步步移动两个指针,当两个指针都指向同一个结点时,返回那个结点 * @param list1 * @param list2 * @return */ public static ListNode getFirstCommonNode(ListNode list1,ListNode list2){ if(l

求单链表倒数第k个结点

题目: 输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针. 分析: 设置两个指针p1,p2.首先p1和p2都指向head.然后p2向前走k步,这样p1和p2之间就间隔k个节点,然后p1和p2同.... #include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; struct ListNode{ char data; ListNode* next;