1、如何计算算法的时间复杂度
在计算算法时间复杂度时有以下几个简单的程序分析法则:
1.对于一些简单的输入输出语句或赋值语句,近似认为需要O(1)时间
2.对于顺序结构,需要依次执行一系列语句所用的时间可采用大O下"求和法则"
求和法则:是指若算法的2个部分时间复杂度分别为 T1(n)=O(f(n))和 T2(n)
=O(g(n)),则 T1(n)+T2(n)=O(max(f(n), g(n)))
特别地,若T1(m)=O(f(m)), T2(n)=O(g(n)),则 T1(m)+T2(n)=O(f(m) + g(n))
3.对于选择结构,如if语句,它的主要时间耗费是在执行then字句或else字句所用
的时间,需注意的是检验条件也需要O(1)时间
4.对于循环结构,循环语句的运行时间主要体现在多次迭代中执行循环体以及检验
循环条件的时间耗费,一般可用大O下"乘法法则"
乘法法则: 是指若算法的2个部分时间复杂度分别为 T1(n)=O(f(n))和 T2
(n)=O(g(n)),则 T1*T2=O(f(n)*g(n))
5.对于复杂的算法,可以将它分成几个容易估算的部分,然后利用求和法则和乘法
法则技术整个算法的时间复杂度
另外还有以下2个运算法则:
(1) 若g(n)=O(f(n)),则O(f(n))+ O(g(n))= O(f(n))
(2) O(Cf(n)) = O(f(n)),其中C是一个正常数
可以用以上法则对下面程序段进行简单分析
①for (i=0; i<n; i++)
② for (j=0; j<n; j++)
{
③ c[i][j] = 0;
④ for (k=0; k<n; k++)
⑤ c[i][j]= c[i][j]+ a[i][k]* b[k][j];/ * T5(n) = O(1) */
}
第①条与②③④⑤是循环嵌套T1(n)*T2(n)* (T3(n)+ T4(n)* T5(n))= O(n*n*n)
即为整个算法的时间复杂度
O(1)<O(log2n)<O(n)<O(n log2 n)<O(n^2)<O(n^3)<O(2^n)
2、判断两个链表是否相交(来自《编程之美》):
在两个链表没有环的前提下,如何判断两个链表是否相交?
解法一:嵌套循环,判断第二个链表的每个节点是否在第一个链表中。时间复杂度O(n^2) 也可写、成(O(len(n1)+len(n2))).
解法二:将第一个链表的所有节点存在hash表中(按地址存),遍历第二个节点判断是否在hash表中。时间复杂度:O(n),空间复杂度O(n)。
解法三:将第一个链表的末节点接在第二个链表的头部。然后从第二个链表开始遍历看是否能回到第二个链表的头部,如果能就说明两个链表相交了。如图:
时间复杂度:O(n),因为需要保存第一个节点的末节点(为了恢复现场)和第二个链表的首节点,空间复杂度是常数O(1)。
解法四:如果两个链表有相交的话,最后末节点必须相同。所以首先遍历第一个节点,记忆末节点;然后遍历第二节点,判断末节点是否相同。时间复杂度O(n),而空间的消耗只要存末节点的空间而已。
显然,以上算法中解法四相对优异。
如果,问题变为:
1、链表可能有环,该怎么调整?
链表有环,末节点的下一个节点肯定在链表内部。所以,不管有没有环,先断开末节点的指向,也就是将末节点指向NULL,然后判断第二个链表的末节点和第一个链表是否相同(也即是上面的解法四)。
2、求出第一个相交的节点
分两步: a 不管有没有环,先将末节点指向NULL变为无环
b 用上面的解法二,找出出现第一个出现在hash表中的节点。
- 大小: 11.6 KB
- 大小: 11.9 KB
分享到:
相关推荐
接着遍历h2,计算每个节点的哈希值并查找map,一旦找到匹配项,即表示两个链表相交。这种方法的时间复杂度降为O(max(length(h1), length(h2))),因为最慢的情况是遍历较长的链表。然而,它需要额外的空间来存储哈希...
在实际应用中,尤其是在大型系统开发过程中,可能会遇到两个链表相交的情况。例如,当两个链表共享部分节点时,如果不加以处理就释放其中一个链表的所有节点,将会导致信息丢失,甚至会影响到另一个与之相交的链表。...
考虑到如果两个链表相交,则它们共享的所有节点都将位于最后一个相交节点之后,因此可以考虑通过比较两个链表的最后一个节点来判断它们是否相交。具体步骤如下: 1. 遍历链表 h1,找到最后一个节点。 2. 遍历链表 h2...
6. **链表相交**:现在我们聚焦于相交链表的实现。相交链表是指两个链表在某点之后有共同的节点。一个简单的方法是先分别遍历两个链表,找出它们的长度,然后从较长链表的尾部开始,逐个节点与较短链表比较,直到...
- **相交链表** (问题160):最优解的时间复杂度是O(n+m),空间复杂度是O(1),通过两个指针分别从两个链表的头开始遍历,直到找到交点或遍历结束。 此外,还有其他解题策略,如使用哈希表、栈等数据结构来优化链表...
然而,如果要求在O(1)的时间复杂度内完成插入,可以考虑在链表的头部进行操作,即每次新插入的节点成为链表的第一个节点。 判断链表是否有环是另一个常见的问题。可以通过快慢指针的方法来解决,即同时使用两个指针...
6. **判断链表是否相交**: - **方法1**:遍历第一个链表并记录其最后一个节点,然后遍历第二个链表,如果最后的节点与第一个链表的最后一个节点相同,则相交。 - **方法2**:将两个链表连接,如果新链表存在环,...
本题目要求给出两个单向链表的头指针,判断这两个链表是否相交。解决这个问题的关键是正确地设计算法,以 O(n) 的时间复杂度解决问题。 8. 算法题 本题目要求解决一些比较怪的题目,考验思维能力。解决这些问题的...
对于单链表的反转和链表相交问题,需要我们对链表的结构和操作有深入的理解和熟练的掌握,这不仅有助于提升解题效率,也是衡量应聘者是否具备系统编程能力的关键因素。在面试准备中,务必重视这些问题的练习,并尝试...
然后将长链表指针向前移动长度差的步数,最后同时遍历两个链表,如果它们指向同一节点,则链表相交,否则不相交。 问题扩展: 1. 判断二元树是否为二元查找树的后序遍历结果 知识点:二元查找树、后序遍历、二元...
7. **判断链表是否相交**:如果链表不带环,可以分别遍历两个链表到尾部,记录长度,之后从长度短的链表头部开始,按长度差向另一个链表移动,直到相遇则相交,否则不相交。如果链表可能有环,可以使用 Floyd 环检测...
8. 链表相交的第一个节点 这个扩展问题要求不仅判断链表是否相交,而且还要找出相交的第一个节点。解决这个问题需要额外的空间复杂度或时间复杂度。 以上知识点主要围绕着数据结构和算法的面试题目。通过解决这些...
7. **链表相交**: 判断两个链表是否相交可以通过计算它们的长度,然后从较长链表的尾部开始向短链表的方向遍历,直到找到相同节点。如果考虑链表有环,可以使用Floyd判环法或者双指针法来处理。 8. **思维题**: ...
对于可能有环的链表,可以使用Floyd判断环的方法,再判断是否相交。 8. **思维题** 这类问题通常需要跳出常规思路,例如房间与灯泡的问题可能是考察逻辑推理能力,具体解答需要知道题目的完整信息。 以上是数据...
可以采用双指针法,分别从两个链表的头节点开始,快指针每次走两步,慢指针每次走一步,若两个链表相交,则会在某个点相遇。 8. **其他思维题**: 这些题目的解答涉及逻辑思维和创造性思考,如灯泡和开关的问题...
- 点线段关系判断:如点在线上、线段相交等。 - 旋转卡壳法:用于求解凸包问题。 这些算法程序集提供了丰富的实例,帮助学习者巩固理论知识,提高实践能力。通过阅读和理解这些代码,可以加深对算法原理的理解,...
对于没有环的链表,可以分别遍历两个链表,记录各自的长度,然后从较长链表的末尾开始向短链表的方向遍历,直至找到相同节点,表示链表相交。如果链表可能有环,可以使用双指针法,一个快指针每次移动两步,一个慢...
7. **判断链表相交**: - 对于没有环的链表,可以同时从两个链表的头节点开始遍历,直到它们相遇,说明链表相交。 - 如果链表可能有环,可以使用Floyd判断环的方法,同时使用快慢指针,如果快指针最终追上慢指针,...
如果链表不带环,可以分别遍历两个链表,记录它们的长度,然后从较长链表的尾部开始,每次向后移动短链表长度的距离,直到两个指针相遇或者其中一个到达链表末尾,说明链表相交。如果链表可能有环,可以使用两个...
链表160相交+92翻转链表2+142环形链表2.mp434.100+101二叉树刷题.mp435.树的迭代写法 144+100.mp436.树形结构刷题111+114.mp437.刷题617+236.mp438.刷题543二叉树的执行+572是否是子树.mp439.572+222+257树结构.mp...