按K元素分组反转链表算法实现思路及代码

1、问题:给定链表,对链表中的元素,每K个一组,组内元素反转,不足K个不动

2、思路

1)先实现链表(使用头插法)

2)对链表迭代元素,一旦找到第K个元素,则可知本组内第一个和最后一个元素

3)组内元素反转,返回本组首位元素

4)迭代计数器重置,记录反转的组的原最后一个元素的下一个元素,所谓下一组的第一个元素,

记录反转后的首位元素

5)如果上个组的首位元素记录值不为空,则拼接两个反转后的组

3、结果截图。11个元素,3个一组结果展示

4、代码

public class ReverseDemo {


    @Getter
    @Setter
    public static class Element{

        private Node head;
        private Node tail;

        //头插
        public void addNode(Object value){

            Node node = new Node(value);
            if(head == null){
                head = node;
                tail = node;
                return;
            }

            Node lastHead = head;
            head = node;
            head.next = lastHead;
            lastHead.pre = head;
        }
        public String printNodes(){
            StringBuilder sb = new StringBuilder();
            Node tmp = head;
            while (tmp != null){
                sb.append(tmp.getValue()).append(",");
                tmp = tmp.next;
            }
            return sb.toString();
        }
        public String toString(){
            return "Element[" + hashCode() + "]";
        }
    }
    @Getter
    @Setter
    public static class Node<T>{
        private Node<T> pre;
        private Node<T> next;
        private T value;
        public Node(T t){
            this.value = t;
            this.pre = null;
            this.next = null;
        }
    }

    public static void main(String[] args) {
        Element element = initElement();
        System.out.println(element.printNodes());
        Element element1 = reverseElement(element, 3);
        System.out.println(element1.printNodes());
    }

    public static Element initElement(){
        Element element = new Element();

        for (int i = 0; i < 11; i++) {
            element.addNode(i);
        }
        return element;
    }

    public static Element reverseElement(Element element, int k){

        Node cur = element.getHead();
        Node groupStart = cur;
        Node groupEnd = null;
        int capital = 1;
        Node preGrouphead = null;
        Node resultHead = null;
        while(cur.next != null){

            Node next = cur.getNext();
            cur = next;
            capital++;
            if(capital != k){
                continue;
            }
            capital = 1;
            groupEnd = next;
            cur = cur.next;
            Node headAfterReverse = getHeadAfterReverseGroup(groupStart, groupEnd);
            if(resultHead == null){
                resultHead = headAfterReverse;
            }
            groupStart = cur;
            connect2Group(preGrouphead, headAfterReverse);
            preGrouphead = headAfterReverse;
        }
        if(groupEnd != cur){
            connect2Group(preGrouphead, groupStart);
        }
        if(resultHead == null){
            resultHead = element.getHead();
        }

        Element element1 = new Element();
        element1.setHead(resultHead);
        return element1;
    }

    public static Node getHeadAfterReverseGroup(Node groupStart, Node groupEnd){

        Node tmp = groupStart;
        Node pre = null;
        Node next = null;
        while (tmp.pre != groupEnd){
            next = tmp.next;
            tmp.pre = next;
            tmp.next = pre;
            pre = tmp;
            tmp = next;
        }
        return groupEnd;
    }

    public static void connect2Group(Node preGroupHead, Node curGroupHead){

        if(preGroupHead == null || curGroupHead == null){
            return;
        }
        Node lastNode = preGroupHead;
        while (lastNode.next != null){
            lastNode = lastNode.next;
        }
        lastNode.setNext(curGroupHead);
        curGroupHead.setPre(lastNode);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值