二进制是因为
组成计算机系统 的逻辑电路
只有两个状态
开关的接通与断开
二进制的数据表达具有抗干扰能力强、可靠性高的优点。
用十进制设计具有 10 种状态的电路,情况就会非常复杂,判断状态的时候出错的几率就会大大提高
二进制也适合逻辑运算,真假和1,0正好匹配
逻辑右移 左边补0 >>>
算数右移 负数 左边补1 (符号位不变) >> I
java的bigInteger用于进制转换
余数可以判断
N天后是星期几
余数一定小于除数,因为除数是每组的大小。多出的一组一定小于这个单位
hash是将任意长度输入,通过hash算法,得到固定长度输出,很像余数
设计散列表就像设计周一到周日的日期号,余数相同的在一个周一里
公式为f(x)=x%size,size指有限空间的数目,也就是有多少个框框装东西,不是框框本身的容量
也可以f(x)=(x+random)%size 增大随机性
加密一个三位数:比如625,取随机数是 590127。那单独取出百、十和个位分别加上这个随机数,就变成了 590133,590129,590132。然后,三位分别除以 7 求余后得到 5,1,4。最终,我们可以得到加密后的数字就是 415
迭代是根据前面每一步,计算后面
递归是自己调用自己
求方程的精确或近似解,二分求平方根
查找匹配记录,二分比较是否匹配用.comparTo
机器学习算法中的迭代
数学归纳法:
证明基本情况(通常是 n=1 的时候)是否成立;
假设 n=k−1 成立,再证明 n=k 也是成立的(k 为任意大于 1 的自然数)。
是一个证明假设再证明的过程
递归最大好处:保存中间状态和变量值
目的是简化成更小,更简单的子问题
归并和背包组合问题一样,都是先加再减。代码先写减完的边缘条件
Arrays.copyOfRange
对应MapReduce就是
数据分割
洗牌
规约
合并
一般递归的两个参数:剩下的内容,已经排好的内容和顺序
排列穷举,也是用递归的代码。赛马分为horses未加入排列的,和result已加入排列的
比如密码暴力破解也是排列组合,n个数里取m个做密码。就是n^m次方。加上特殊符号需要十年破解密码
public static void permutate(ArrayList<String> horses, ArrayList<String> result) {
// 所有马匹都已经出战,判断哪方获胜,输出结果
if (horses.size() == 0) {
System.out.println(result);
compare(result, q_horses);
System.out.println();
return;
}
for (int i = 0; i < horses.size(); i++) {
// 从剩下的未出战马匹中,选择一匹,加入结果
ArrayList<String> new_result = (ArrayList<String>)(result.clone());
new_result.add(horses.get(i));
// 将已选择的马匹从未出战的列表中移出
ArrayList<String> rest_horses = ((ArrayList<String>)horses.clone());
rest_horses.remove(i);
// 递归调用,对于剩余的马匹继续生成排列
permutate(rest_horses, new_result);
}
}
组合也是t2后就不需要考虑t1了,因为已经出现过
所以递归参数是没有组合的队伍teams,和已经组合的队伍result
teams用subList更新,左闭右开,会影响原来的
public static void combine(ArrayList<String> teams, ArrayList<String> result, int m) {
// 挑选完了 m 个元素,输出结果
if (result.size() == m) {
System.out.println(result);
return;
}
for (int i = 0; i < teams.size(); i++) {
// 从剩下的队伍中,选择一队,加入结果
ArrayList<String> newResult = (ArrayList<String>)(result.clone());
newResult.add(teams.get(i));
// 只考虑当前选择之后的所有队伍
ArrayList<String> rest_teams = new ArrayList<String>(teams.subList(i + 1, teams.size()));
// 递归调用,对于剩余的队伍继续生成组合
combine(rest_teams, newResult, m);
}
}
}
DP通过子问题最优解,推导最终最优解
利用编辑距离进行查询推荐
状态转移方程:
复杂度m*n,比原理m^n好太多了
要注意dp[i][j]和a[i],b[j]是不同的
什么时候用DP:看上去有很多可能,要用排列组合思想,但是其实只是在求最优解
Leetcode72题
前缀树是一种有向树
树的高度是除了根节点外,数数
前缀树是一个典型应用,运用了深度遍历(用栈)