冷静 集中 专注 努力
算法之路
这段时间接触链表相关的算法,其中双指针的思想的应用可以说是链表算法中的一个很常见的场景,今天看到了一个算法,也是使用双指针来完成的,在此记录一下
在不知道链表长度的情况下,如何找到链表的倒数第n个节点
第一眼看到这个题目的反应,就是遍历先去取得链表的长度,然后再正序去取链表长度-n个节点,这样可能是最方便的方法,但是这样时间复杂度就提高了,需要遍历两次链表。
第二个方法就是用队列把链表的数据存储下来放到队列里,使用队列先进后出的特性来取链表的倒数第n个节点,这样的话不好的一点就是需要增加队列的一个使用了。
第三个方法就是使用双指针法,也称快慢指针在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。LeetCode上相关双指针的算法还是很多的。
开篇算法题的解法如下:
/**
* @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
双指针的方法处理很多链表相关的问题都很方便,尤其是有关遍历的复杂问题很可能到最后都是使用啥双链表最方便,最近有时间的话好好整理一下。
这是一个很慢很长的过程,所以请别着急
这是一个很慢很长的过程,所以请别着急