双指针的技巧

1.数据交换的时候,剑指offer21题。

2.查找链表中的倒数第k个数字,剑指offer22题。

package com.company;

public class NumberK {
    static class Node{
        public Node(int value){
            this.value = value;
        }
        int value;
        Node next = null;
    }

    public static void main(String[] args){
        Node n1 = new Node(1);
        Node n2= new Node(2);
        Node n3= new Node(3);
        Node n4= new Node(4);
        Node n5= new Node(5);
        Node n6= new Node(6);
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;

        int value = getNumberKey(n1,1);
        System.out.println("倒数第k个数是 "+value);

    }

    public static int getNumberKey(Node node ,int k){
        if(node == null) return -1;
        if(k <= 0) return -1;
        Node fisrtNode = node;
        Node lastNode = node;
        while (k-1 > 0){
            if(fisrtNode.next != null){
                fisrtNode = fisrtNode.next;
                k--;
            } else {
                return -1;
            }
        }
        while (fisrtNode.next!=null){
            fisrtNode = fisrtNode.next;
            lastNode = lastNode.next;
        }
        return lastNode.value;
    }
}

3.剑指offer第23题。

package com.company;

public class EnterNode {
    static class Node{
        public Node(int value){
            this.value = value;
        }
        int value;
        Node next = null;
    }

    public static void main(String[] args){
        Node n1 = new Node(1);
        Node n2= new Node(2);
        Node n3= new Node(3);
        Node n4= new Node(4);
        Node n5= new Node(5);
        Node n6= new Node(6);
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;
        n6.next = n5;

        System.out.println("初始环的值是 "+getEnterNode(n1).value);

    }

    public static Node getEnterNode(Node node){
        if(hasCircle(node)){
            int count = getCircleCount(node);
            return getFirstNode(node,count);
        }
        return null;
    }

    /**
     * 第一个指针领先第二个指针一个环的位置,
     * 然后第一个指针和第二指针依次向后遍历,第一次相遇时,就是环的开始位置
     * @param node
     * @param num
     * @return
     */
    public static Node getFirstNode(Node node, int num){
        Node firstNode = node;
        Node secondNode = node;
        while (num > 0){
            firstNode = firstNode.next;
            num--;
        }
        while (firstNode != secondNode){
            firstNode = firstNode.next;
            secondNode = secondNode.next;
        }
        return firstNode;
    }


    /**
     * 快指针追到满指针后,慢指针再次回到当前位置走步数就是换的个数
     * @param node
     * @return
     */
    public static int getCircleCount(Node node){
        Node twoStep = node;
        Node oneStep = node;
        twoStep = twoStep.next.next;
        while (twoStep != oneStep){
            twoStep = twoStep.next.next;
            oneStep = oneStep.next;
        }
        int count = 1;
        Node tempNode = oneStep;
        while (tempNode != oneStep.next){
            count++;
            oneStep = oneStep.next;
        }
        return count;
    }

    /**
     * 慢指针追上快指针就有环
     * @param node
     * @return
     */
    public static boolean hasCircle(Node node){
        Node towStepNode = node;
        Node oneStepNode = node;
        if(node == null) return false;
        if(towStepNode.next == null || towStepNode.next.next == null) return false;
        while(towStepNode.next.next != null){
            if(towStepNode == oneStepNode) {
                return true;
            }
            if(towStepNode.next == null) {
                return false;
            }
            towStepNode = towStepNode.next.next;
            oneStepNode = oneStepNode.next;
        }
        return false;
    }

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值