双指针解决链表遍历

​ 冷静 集中 专注 努力

算法之路

​ 这段时间接触链表相关的算法,其中双指针的思想的应用可以说是链表算法中的一个很常见的场景,今天看到了一个算法,也是使用双指针来完成的,在此记录一下

在不知道链表长度的情况下,如何找到链表的倒数第n个节点

​ 第一眼看到这个题目的反应,就是遍历先去取得链表的长度,然后再正序去取链表长度-n个节点,这样可能是最方便的方法,但是这样时间复杂度就提高了,需要遍历两次链表。

​ 第二个方法就是用队列把链表的数据存储下来放到队列里,使用队列先进后出的特性来取链表的倒数第n个节点,这样的话不好的一点就是需要增加队列的一个使用了。

​ 第三个方法就是使用双指针法,也称快慢指针在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。LeetCode上相关双指针的算法还是很多的。

img

开篇算法题的解法如下:

/**
 * @description: 使用双指针的方法寻找链表的倒数第n个节点(未知链表长度)
 * @author: zhanghailang
 * @date: 2020-10-19 9:35
 */
public class NumFromEnd {

    /**
     * 查找倒数第n个节点
     * @param head
     * @param n
     * @return
     */
    public static Node findNumFromList(Node head,int n){
        Node p1 = head;
        Node p2 = head;
        for (int i = 1; i < n; i++){
            p2 = p2.next;
            if(p2 == null){
                throw new IllegalArgumentException("参数超出链表长度");
            }
        }
        while (p2.next != null){
            p1 = p1.next;
            p2 = p2.next;
        }
        return p1;
    }


    /**
     * 快速的创建一个链表
     * @param array
     * @return
     */
    private static Node buildNodeList(int[] array){
        Node head = new Node(array[0]);
        Node p = head;
        for (int i = 1; i < array.length; i++){
            p.next = new Node(array[i]);
            p = p.next;
        }
        return head;
    }

    /**
     * 静态内部类  node节点
     */
    public static class Node{
        int data;
        Node next;
        Node(int data){
            this.data = data;
        }
    }

    public static void main(String[] args) {
        int[] arrays = {1,3,10,2,9,11,99,222,33};
        Node head = buildNodeList(arrays);
        Node node = findNumFromList(head,3);
        System.out.println("链表的倒数地三个节点是:" + node.data);
    }
}

输出结果为:

	链表的倒数地三个节点是:99

​ Process finished with exit code 0

​ 双指针的方法处理很多链表相关的问题都很方便,尤其是有关遍历的复杂问题很可能到最后都是使用啥双链表最方便,最近有时间的话好好整理一下。


​ 这是一个很慢很长的过程,所以请别着急

                                                                             这是一个很慢很长的过程,所以请别着急

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值