算法随笔

来源:互联网 发布:aes256 加密java代码 编辑:程序博客网 时间:2024/05/16 14:34



今天,看见了几个问题,感觉以后可能自己还会遇到,所以就先记下来。

 1.有两个单链表La和Lb,现求它们的第一个共同结点。如下图:

方法一:

   通过遍历两个链表,对比next域中的地址,看是否相同,直到找到第一个相同的地址,那它就是第一个共同结点。但它的时间复杂度为O(n^2).

方法二.

使用两个栈,分别将两个链表的next域地址入栈,之后同时出栈,并记录当前出栈的值,出栈直到第一次出现两栈中的数据不相等时停止,那么就能找到第一个共同节点了。它的时间复杂为O(n),空间复杂度为O(La_len+Lb+len).

方法三.

首先遍历两个链表,记录链表长度La_len,和Lb_len,算出长度差len = abs(La_len-Lb_len) ,

然后,从最长的链表的第len个节点开始,和另一个链表同时遍历比较next域指针是否相同,直到找到第一个相同的节点(如果没有,直到最短链表尾截至)。它的时间复杂度为O(n),而且还不用申请额外的空间,所以这个算法还算高效的。

方法四.

这个方法相对与上面的来说效率不是多高,操作也相对复杂点,误差也较大(这与哈希函数的构建有关),就是用哈希,将一个链表的next域指针地址哈希后,将得到的value值保存在数组中,还要考虑冲突问题,可用连地址法解决冲突,之后将另一条链表也通过此哈希函数求值并和数组中的值进行对比,找到第一个冲突节点。

 

2. 找到单链表的倒数第k个节点。

方法一:

遍历链表,将链表的的next域入栈,之后再进行出栈操作,直到出栈到第k个数停止。

方法二:

  定义两个指针变量p1,p2,首先,让p1指针先遍历到第k个节点,之后,p2从头节点开始和p1同时向后遍历,直到p1到达尾节点停止,此时,p2所指的节点就是倒数第k

个节点。

 

3. 从n个数中找出第k大数(1<k < = n)。

 

 可以使用堆来查找,首先构建一个有k个数的小顶堆,然后,从剩下的数中取一个数和堆根数比较,如果比堆根数还小,则接着取下一个数,否则,就替换掉堆根,然后再进行堆调整,之后,继续取数和堆根比较,当n个数都进行上诉操作后,最后所维护的堆就是n个数中前k个大数,而堆根就是第k大数。主要思想就是,添加一个数和堆中最小数进行比较,之后提出最小的数,加入新的数,如果换作大顶堆,那我们还要在所有的叶子中找到最小值,之后再和加入的数进行比较,这样就比较麻烦了,所以维护一个小顶堆,可直接找到最小值。








0 0
原创粉丝点击