掘金更文挑战
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
专栏 —— 算法Trick
更新一些面试或刷题时可能会用到的小算法,小技巧,脑筋急转弯。是一些你知道就能更快更优雅,不知道就会很伤脑筋的小知识。
一、欧几里得算法
又称辗转相除法,求最大公约数
欧几里得算法(Euclidean Algorithm)
return b == 0 ? a : gcd(b, a % b);
二、如何不用临时变量交换变量
| 执行 | a的值 | b的值 |
|---|---|---|
| a = a+b | a + b | b |
| b = a - b | a + b | a |
| a = a - b | a + b - a = b | a |
同理
| 执行 | a的值 | b的值 |
|---|---|---|
| a = a - b | a - b | b |
| b = b + a | a - b | b + a - b = a |
| a = b - a | a - a + b = b | a |
x ^ x = 0
x ^ 0 = x
异或运算满足交换律和结合律
| 执行 | a的值 | b的值 |
|---|---|---|
| a = a ^ b | a ^ b | b |
| b = a ^ b | a ^ b | a ^ (b ^ b) = a |
| a = a ^ b | a ^ b ^ a = (a ^ a) ^ b = b | a |
如果a , b 引用同一个变量, 所以a , b的数值可以相等,但不能是同一个变量。
| 执行 | a的值 |
|---|---|
| a = a ^ a | 0 |
| a = a ^ a | 0 |
| a = a ^ a | 0 |
三、埃氏筛
基于某数的倍数一定不是质数,埃氏筛算法可以以O(n)的复杂度快速筛选出一定范围内的质数。
四、弗洛伊德循环查找算法
即俗称的快慢指针,查找链表中是否存在环。
跟踪链表中的两个指针,快跑者每次更新两步,慢跑者每次更新一步。如果链表中存在循环,那么有限次后,二者一定会相遇。
初始化可以将fast先设一步,然后以快慢指针不相等为循环条件。
public boolean hasCycle(ListNode head) {
if(head == null) return false;
ListNode fast = head.next;
ListNode slow = head;
while(fast != null && fast.next != null && fast != slow){
fast = fast.next.next;
slow = slow.next;
}
return fast == slow ? true:false;
}
五、摩尔投票法
用于搜索数组中的主要元素(即占据二分之一以上的元素) 优点是时间复杂度O(n),且空间复杂度O(1)。
Boyer-Moore 投票算法的基本思想是:在每一轮投票过程中,从数组中删除两个不同的元素,直到投票过程无法继续,此时数组为空或者数组中剩下的元素都相等。
如果数组为空,则数组中不存在主要元素; 如果数组中剩下的元素都相等,则数组中剩下的元素可能为主要元素。