文章目录
- 摩尔投票法
- DFS算法
- BFS算法
题源来自于力扣网
摩尔投票法
-
适用场景
如何在选票无序的情况下,选出获胜者。 -
例题:
找出数组中,出现次数超过总数一半的数字(出现次数 > n/2)。输入:[1,1,3,2,4,6,2,2,2,2,2]; 输入:2
-
思路:
- 排序算法。
出现次数 > n/2,那么把数组排序后,nums[n/2] 必定就是出现次数最多的数。 - 摩尔算法
只要两个数不相同,这两个数就可以相互抵消,最后剩下的就是要的结果。听起来不太理解。简单点说,上题中,因为结果数cand_num过半,所以永远不可能被抵消完,所以最后剩下的就是结果。
1,1,3,2,4,6,2,2,2,2,2 // 进行整理 1,1,3,4,6 2,2,2,2,2,2 // 进行相互抵消,最不乐观的情况,也会剩下一个 2(也可能会剩下多个 2 )
排序算法时间复杂度O(n*logn)
摩尔算法时间复杂度O(n),空间复杂度O(1),所以推荐使用摩尔算法 - 排序算法。
-
解题方法
class Solution { public int majorityElement(int[] nums) { int cand_num = nums[0], count = 1; for (int i = 1; i < nums.length; ++i) { if (cand_num == nums[i]) ++count; else if (--count == 0) { cand_num = nums[i]; count = 1; } } return cand_num; } }
DFS算法
-
适用场景
DFS算法,又称为深度优先搜索
,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。
作为搜索算法的一种,DFS对于寻找一个解的NP(包括NPC)问题作用很大。但是,搜索算法毕竟是时间复杂度是O(n!)的阶乘级算法,它的效率非常低,在数据规模变大时,这种算法就显得力不从心了。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。 -
例题
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 解释:等于目标和的根节点到叶节点路径如上图所示。
输入:root = [], targetSum = 0 输出:false 解释:由于树是空的,所以不存在根节点到叶子节点的路径。
-
思路
- dfs算法
根据题意,只要从根节点至叶节点的和,等于targetSum,那么这个路径就符合要求。所以我们需要以此查询每一条路径,直到找到结果或者全部遍历完为止。我们可以采用递归,每次进去下一个节点,都减去当前节点的值。如果到了叶节点,正好此时targetSum为0,那么这条路径就符合要求。
- dfs算法
-
解决方法
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public boolean hasPathSum(TreeNode root, int targetSum) { return search(root,targetSum); } boolean search(TreeNode root,int targetSum){ if(root == null) return false; targetSum -= root.val; // 判断此节点是叶节点(没有子节点的节点,也叫叶节点),且targetSum正好是0,则符合要求 if(root.left == null && root.right == null) return targetSum == 0; // 不是叶节点,进入下一层节点进行搜搜 return search(root.left,targetSum) || search(root.right,targetSum); } }
BFS算法
-
适用场景
广度优先算法(Breadth-First-Search),简称BFS。从知识点看属于图结构的搜索算法,是一种相对容易理解的简单算法。
BFS算法从问题的初始状态(起点)出发,根据状态转换规则(图结构中的边),遍历所有可能的状态(其他节点),直到找到终结状态(终点)。因此BFS算法的复杂度和状态集合的总数密切相关。
BFS算法虽然出自图结构,但其常用的领域却不是解决图论相关问题。一些常见的问题形式如(1)走迷宫最短路径(2)数字按规则转换的最少次数(3)棋盘上某个棋子N步后能到达的位置总数(4)病毒扩散计算(5)图像中连通块的计算。小结:BFS算法常用于求最短的步数或者求扩散性质的区域问题。 -
例题
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
输入:p = [1,2,3], q = [1,2,3] 输出:true
输入:p = [1,2], q = [1,null,2] 输出:false
-
思路
- bfs广度优先搜索
例题1中,我们可以先比较第一层,第一层完全相同后,比较第二层,如果完全相同,则比较第三层…,直到找到结果。
- bfs广度优先搜索
-
解决方法
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) { return true; } else if (p == null || q == null) { return false; } Queue<TreeNode> queue1 = new LinkedList<TreeNode>(); Queue<TreeNode> queue2 = new LinkedList<TreeNode>(); queue1.offer(p); queue2.offer(q); while (!queue1.isEmpty() && !queue2.isEmpty()) { TreeNode node1 = queue1.poll(); TreeNode node2 = queue2.poll(); if (node1.val != node2.val) { return false; } TreeNode left1 = node1.left, right1 = node1.right, left2 = node2.left, right2 = node2.right; if (left1 == null ^ left2 == null) { return false; } if (right1 == null ^ right2 == null) { return false; } if (left1 != null) { queue1.offer(left1); } if (right1 != null) { queue1.offer(right1); } if (left2 != null) { queue2.offer(left2); } if (right2 != null) { queue2.offer(right2); } } return queue1.isEmpty() && queue2.isEmpty(); } }