1111111111111 算法汇总

如何找到两个相交链表对交点?

如果两个单向链表有公共节点,则两个链表会构成Y型结构,最后一个节点相同
我们可以从头开始遍历两个链表,找到最后一个节点的指针,设为p_a,p_b。同时记录下两个链表的长度len_a,len_b(假设len_a >= len_b)。
如果p_a == p_b,则说明两个链表有公共节点,否则没有。
如果有公共节点,则第一个公共节点距起始节点的距离满足 len_a - start_a == len_b - start_b。
所以第一个可能的公共节点距起始节点的距离是 len_a - len_b, 0。我们从这两个节点开始比较,直到找到第一个公共节点。

 

单向链表中,如何在给定节点前快速插入一个节点?

对于单向链表来说,在某个节点后面插入一个新节点是非常快的。
所以我们可以在给定节点后面插入一个新节点,然后交换给定节点和新节点的数据即可。

 

找到链表的倒数第m个节点

方法1:
首先遍历链表,统计链表的长度N。
然后再次遍历链表,找到第N-m+1个节点,即为倒数第m个节点。

方法2:
使用两个指针,并使它们指向的节点相距m-1个。
然后同时向前移动两个指针,当一个指针指最后一个节点时,第二个指针指向倒数第m个节点。


两个方法的复杂度都是O(n)。
但是当N较大而m较小时,方法2可能会更快一些。因为方法2能更好利用CPU的缓存。

更多阅读:
http://baike.baidu.com/view/2089.htm  CPU -> 缓存

 

找出数组中的众数,众数值出现次数大于数组长度一半的数?

1.逐个统计每个数出现的次数,时间复杂度为O(n*n)(n*(n-1)/2+n),n指数组元素的个数。

2.对数组进行排序,得出中间(n/2)元素就是众数。证明用反证法,如果中间元素不是,则众数出现的次数小于一半。排序可以用计数排序O(n)达到最好,最后的结果也是最好。

3.上述排序的方法虽然时间复杂度是线性的,但是还有一定的计算量。试想,既然众数是出现次数大于一半的数,那么对数组每次删除两个不同元素(不管是否包含众数)后得到的子问题应该和原问题在本质上没有改变。

 

Int数组,局部最大值?

 

2-sum问题,Int数组,找出所有两个数相加为N?

先排序,然后用两个指针分别指向头和尾,看是否符合条件,不断向中间靠拢继续找。

 

N-sum问题:

 

2-diff问题:Int数组,找出两个数的差为N的所有数?

先排序,用两个指针,i从0开始向右移动,j从0开始向右移动,找到0位的数+N的值,有就找到一对,i向右移动一位,j继续刚的位置向右移动匹配,如果没有找到,i继续移动,j继续从当前位置向右匹配,知道j到数组结尾。

 

给一个数组,找出从1开始,第一个缺失的正整数?

1.暴力; 2.先快排 后遍历数组找出  O(N*lgN)

3.由找出从1开始缺失的正整数,数组长度为N,可知:第一个缺失的正整数肯定介于1~N之间,极端情况下1~N都有。那么可以申请一个同等长度的数组,先便利一遍原数组,当数组中出现1~N之间的数字时,将新数组的相应坐标下的空间保存数字1,遍历完只有,出现1~N的数字向对应在新数组的坐标位置都设置成1了,所以再遍历一遍新数组,找出第一个0的坐标即为所求。 时间和空间复杂度都是O(N)

4.循环不变式

    如果某命题为初始为真,且每次更改后仍然保持命题为真,则若干次更改后该命题仍然为真。

    通过循环不变式解这个题的思路:将找到的元素放到正确的位置上,如果最终发现某个元素一直没有找到,则该元素即为所求。 时间复杂度O(N),空间复杂度O(1)

 

查找旋转数组的最小值

假定一个排序数组,以某个元素为支点做了旋转,如原数组0 1 2 4 5 6 7 旋转后得到4 5 6 7 0 1 2。

请找出一个旋转数组的最小值?

通过二分法查找:找到数组中间位置的数组,与头数字比较,如果头数字小,说明前半截数据是正常的,悬转的部分在后面,即最小值在后面,同理对后面的再做二分,知道找到最小值。

 

有一个天平,和12个硬币,其中有一个假币,假币比真币可能重也可能轻,请问最少称几次可以找出假币?

    3次可称出。方法如下:

    1:将12个硬币分成3等分,任意两份上⚖️,有2种结果:

        1.1平衡    (可知,假币在没上天平的这份里)

            2 从没上天平的4个硬币里随便拿两个上天平

                2.1 平衡    (可知,假币在没上天平的这两个里) 

                    3.将天平上任意一个替换没上⚖️这里的一个 

                        3.1 平衡,说明剩下这个是假币

                        3.2不平衡,说明刚拿上来的这个是假币

                2.2 不平衡 (可知,假币在上天平的这两个里)

                    3.将任意一个币替换天平上的任意一个

                        3.1平衡  说明被替换的是假币

                        3.2不平衡 说明未被替换的是假币

        1.2不平衡 (可知,假币在上天平的这两份里)

            给天平上硬币编号:左边为1234,右边为5678。

            将678拿走,34放在右边,再拿一个真的放在右边,5放在左边。

            2.天平此时左边125,右边34真。

                2.1 平衡,可知假币在678里,根据1.2时不平衡时,5678是高还是低,知道假币是轻是重

                    3.将67放在天平上,

                       3.1平衡 说明8是假币

                       3.2 不平衡,结合假币是轻重的结论可知哪个是假币。

                2.2 不平衡 (结合1.2假币是轻重,继续判断)

                    可以判断,是12里有假币/34里有假币/5是假币,

                3.在用真的对比测出结论

 

 

 

 

 

 

 

 

 

 

http://www.cnblogs.com/skywang12345/category/508186.html

 

https://mp.weixin.qq.com/s/L2aHTwMypVB5eH0Wu9X28A

转载于:https://my.oschina.net/u/3705388/blog/1601342

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值