编程导航算法通关村第一关|白银关1

寻找两个链表的第一个公共子节点

        通过参加通关村的打卡活动,我也希望自己能够养成每天写一些blog的习惯,每天要做的事情很多,要学的东西也很多,每天也在不断地记录一些笔记 -— Java、DT、CN、OS等等,但总归还是一个不断输入的过程。每天晚上学到最后,躺在床上总会问自己今天学到了一些什么,却总会有一些啥也没学到的失落感。Coding以及写blog对我来说就是一个输出的过程。有时学到一些算法思想和编程技巧,就会觉得自己好像掌握了这个知识点,但是真正在写代码和blog的时候总会发现自己出现例如边界、异常等这样那样的问题。或许当我能真正的写出一个0 Warning 0 Error的程序以及一篇让自己感觉不错的blog的时候,我才能真正的搞明白这些算法的原理。与诸君共勉。

——前言

问题:

编程导航算法通关村第一关|白银关1_第1张图片

         此问题在链表题目中也算一个经典题目了:寻找两条链表的相交节点C1,在做这道题之前首先应该明确A和B属于链表,那么就满足链表的一些基本属性:1 链表的每个元素都只知道自己的位置以及下一个节点的位置,父节点位置未知;2 链表在程序设计中以对象作为其存在形式,也就是每一个节点都会在堆区开辟一个独立的空间进行存储,即使两个节点中存的数据相同,两个节点的内存空间也就是地址是不同的,这一点就要和String类相区别。

1 哈希和集合方法

        首先什么是HashSet;HashSet的底层是由HashMap实现的,HashMap的提出是为了解决数组不容易插入和删除,链表不容易查找的问题而提出的。HashMap由数组,链表和红黑树组成的一种数据结构,每一个存入的数据都会自动的分配一个HashCode,Hash表通过HashCode计算出他要存放的数据位置,然后放到数组中的某一个空间位置,当该位置被其他数据占据的时候,HashMap就会将其打包成一个节点,挂载到这个数组位置的后面,依次类推,当该位置的数据达到8个以及数组中的其他位置都被填满以后,这8个节点就会树化,变成红黑树。

        那么为什么此题可以用HashSet解决?HashSet中一个十分重要的特点的就是:他能够存储null数据但是不能存放相同的数据,也就是同一个数据在HashSet中不能存放两次。因此我们只需要将A链表放入到HashSet中,然后再将B链表的元素也逐个放入,当B链表放到C1节点的时候,插入函数就会返回false,那么此时就可以确定C1节点是A与B的公共节点。那么此题的时间复杂度是O(n),空间复杂度是O(n)。

2 栈方法

        什么是栈,栈也是一种存储数据的数据结构,他最大的特点就是FILO(First in Last out),那么根据这个提点我们就可以将A链表和B链表压入两个不同的栈,然后根据栈的FILO的特点,那么程序输出的顺序就是:

        A : C3 -> C2 -> C1 -> A2 -> A1;

        B: C3 -> C2 ->C1 ->B3 -> B2 -> B1;

        由此当第4个节点出栈的时候,两个节点的地址就不同了,那么就可以确定C1是两个链表的公共节点。此时间复杂度是O(n),空间复杂度也是O(n)。

        也可以看出虽然链表只能从前向后依次得出结果,但是压入栈以后就可以从后向前输出结果了。

3 对齐两个链表

        为什么要对其两个链表?首先由于A 和B的长度并不相同,因此他两个同时到达公共节点的时间并不相同?如果能够通过某种处理可以让A和B通过相同的步骤同时到达公共节点的时候,就可以直接得到结果!

3.1 拼接两个链表

       将AB BA分别拼接成两个链表会得到什么结果?

        链1: A1 -> A2 -> C1 -> C2 -> C3 -> B1 -> B2 ->B3 -> C1 -> C2 -> C3;

        链2: B1 -> B2 ->B3 -> C1 -> C2 -> C3 -> A1 -> A2 -> C1 -> C2 -> C3;

        通过拼接两个链表我们发现什么?两个链表的长度相等了,同时两个链表的公共区域(红色区域)处在了同一个位置! 两个链表前面的相同区域(绿色部分)由于A链和B链本身的长度不同而不会同时相遇.此题的时间复杂度O(n), 空间复杂度O(n).

        那么我们再同时将两个链表从前向后遍历的时候就可以得到公共节点.

3.2 差和双指针

        差和双指针是什么,由上面的思路我们可以得到如果能够让A链表的上的指针和B链表上的指针同时达到公共节点处就应该让两个链表对齐.因此得到的一个思路就是,分别遍历两个链表得到其长度LA和LB, 判断LA和LB的长度,此题中,LB>LA 用LB-LA就能得到两个链表的长度差,让B链表指针先走LB-LA步,然后两个链表的指针同时走就能同时到达公共节点处. 此解法的时间复杂度是O(n),空间复杂度是O(1).

4 思路总结

        在算法村的学习中,我也get到了一个小技巧,常用的数据结构有:数组,链表,队列,栈,树,图,Hash,集合,堆,常用的算法思想有:查找,排序,双指针,递归,迭代,分治,贪心,回溯,动态规划等.那么很多题目的解法就来自于上述数据结构和算法的排列组合,毕竟祖师爷曾曰过:程序 = 数据结构 + 算法.

你可能感兴趣的:(算法,java,数据结构)