我是靠谱客的博主 机智蓝天,最近开发中收集的这篇文章主要介绍助你刷题LeetCode - 常见算法(持续更新中)动态规划-后一个状态能由前一个状态转换来分治回溯并查集 - 算是否关联前序遍历(先序遍历)中序遍历双指针(快慢指针)从集合中选择满足条件的结果(去重或不去重)快速选择 - 求第K大(小)元素或前K大(小)元素二分查找最小(大)堆,求有序的前K个元素单调栈-划分区间求极致值出度(两端烧绳子求中点,无向图求中点)多源广度(深度)优先搜索求一个集合(数组) 符合某种条件的(真)子集,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
常见算法
- 动态规划-后一个状态能由前一个状态转换来
- 分治
- 回溯
- 并查集 - 算是否关联
- 前序遍历(先序遍历)
- 中序遍历
- 双指针(快慢指针)
- 从集合中选择满足条件的结果(去重或不去重)
- 快速选择 - 求第K大(小)元素或前K大(小)元素
- 二分查找
- 最小(大)堆,求有序的前K个元素
- 单调栈-划分区间求极致值
- 出度(两端烧绳子求中点,无向图求中点)
- 多源广度(深度)优先搜索
- 求一个集合(数组) 符合某种条件的(真)子集
动态规划-后一个状态能由前一个状态转换来
动态规划的关键是推导状态转移方程,常用来解决后一个状态能由前一个状态得出的场景。
面试题 17.09 :有些数的素因子只有 3,5,7,请设计一个算法找出第 k个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/get-kth-magic-number-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public int getKthMagicNumber(int k) {
int[] rArr = new int[k];
rArr[0] = 1;
int n = 1;
int index1 = 0;
int index2 = 0;
int index3 = 0;
while(n != k) {
int val1 = rArr[index1] * 3;
int val2 = rArr[index2] * 5;
int val3 = rArr[index3] * 7;
int min = Math.min(Math.min(val1, val2),val3);
if(min == val1) index1++;
if(min == val2) index2++;
if(min == val3) index3++;
rArr[n] = min;
n++;
}
return rArr[k-1];
}
}
分治
采用分治法解决的问题一般具有的特征如下:
- 问题的规模缩小到一定的规模就可以较容易地解决。
- 问题可以分解为若干个规模较小的模式相同的子问题,即该问题具有最优子结构性质。
- 合并问题分解出的子问题的解可以得到问题的解。
- 问题所分解出的各个子问题之间是独立的,即子问题之间不存在公共的子问题。
设计步骤
- 划分步:把输入的问题划分为k个子问题,并尽量使这k个子问题的规模大致相同。
- 治理步:当问题的规模大于某个预定的阈值n0时,治理步由k个递归调用组成。
- 组合步:组合步把各个子问题的解组合起来,它对分治算法的实际性能至关重要,算法的有效性很大地依赖于组合步的实现。
分治法的关键是算法的组合步。究竟应该怎样合并,没有统一的模式,因此需要对具体问题进行具体分析,以得出比较好的合并算法。
如计算大整数乘积:我们可以将大整数对拆为两个部分。
即a和b相乘就可以写为:a * b = { a1 * 10^(n1/2) + a0 } * { b1 * 10^(n2/2) + b0 }
展开后整理得: a * b = a1*b1 * 10^[ (n1+n2)/2 ] + a1*b0 * 10^(n1/2) + a0*b1 * 10^(n2/2) + a0*b0 ;
实现方法:我们定义一个支持方法f(char *a,char *b),用于在结束递归时(在本例中,我定义有一个数是1位时结束递归,
直接用普通乘法)计算两个字符串的乘积(为了表示大数,用字符串来接受参数)。
有了这个支持方法,分治递归实现两个大数乘法
int f(char *a,char *b)//用字符串读入2个大整数
{
long result = 0;
if(len(a) == 1 || len == 1) //递归结束的条件
result = f(a,b);
else //如果2个字符串的长度都 >= 2
{
char *a1 =a;
*(a1+(len(a)/2))='