随笔分类 - 编程之美
摘要:题目输入: n1, n2, n3, n4 (1~13)输出: 若能得到运算结果为 24, 则输出一个对应的运算表达式如:输入: 11, 8, 3, 5输出: (11-8) * (3*5) = 24思路1. 假设不考虑括号, 4 个数, 每个数只能使用一次, 那就就对 4 个数全排列, 中间有3 个位置插入符号, 共四种符号, 共有 4!*4^3种表达式. 再加上括号, 一共 7680 种.2. 遍历所有变量, 包括运算符, 数字, 括号是一种解法. 首先从集合中任意取出两个数, 对他们进行四则运算(A+B, A-B, B-A...) 然后再放回去即的递归解法. 这种解法效率较低, 存在较多的冗
阅读全文
摘要:1. 朴素 DFS 遍历效率太低, 即便是预先设定 9 个数放到数组再去 DFS, 同样并不高效2. 在生成一个可行解后, 随机删除一些数字, 删除的数字越多, 数独的难度就越大3. 正解二. 3.1假设已经有一个 3X3 的矩阵是排列好的, 具体数字先用字母代替. 将小矩阵放到数独正中间 3.2 通过行变换, 填充数独中间三行 3.3 通过列变换, 填充数独中间三列 3.4 还剩下 4 个小方块, 由相邻的矩阵变换可得
阅读全文
摘要:题目1. 怎么用简单的计算机模型来描述这个问题 ?2. 怎么判断两个图像是否能相消3. 怎么求出相同图形之间的最短距离(转弯数最少)?4. 怎么确定目前处于死锁状态? 如何设计算法来解除死锁?分析1. 在经典最短路径算法中, 需要求出经过格子最少的路径, 而这里, 为了保证转弯数最少, 需要把路径问题的目标函数改成从一个点到另一个点最少的转弯数. 虽然算法的目标函数改了, 但是算法的框架仍然不变.2. 假设现在要解决图形 A 和图形 B 之间的最短路径问题4. 在练练看的最外层加上空白的一层格子5. 首先把图形 A(x1,y1) 加入到队列中, 然后扩展A可以直线到达的格子, 假设这些格子的集
阅读全文
摘要:题目假设有两堆石头, 有两个玩家按照如下规则轮流取石头每个人每次可以从两堆石头中取出数量相等的石头, 或者仅从一堆石头中取出任意数量的石头最后把剩下的石头依次拿光的人取胜首先取石头的人能否赢得这个游戏分析1. 我们先定义先取者有必胜策略的局面为 "安全局面", 而先取者无必胜策略的局面为 "不安全局面"2. 根据枚举 (10,10) 范围内石头的可能组合, 发现不安全局面的局面有 , , ...3. 不安全局面的特点是 b = a + i, i = 1, 2, 3.., 若 a1, b1, ... an-1, bn-1 已经求得, 则定义 an 为未出现
阅读全文
摘要:题目有 N 块石头河两个玩家 A 和 B. A 先将石头分成若干堆, 然后按照 BABABA... 的顺序轮流取石块, 能将剩下的石头依次取光的玩家获胜. 每次取石头时, 每个玩家只能取一堆的 m(m>=1) 个石头思路1. 依然举例子.当 N = 1 时, 输. N = 2 时, 可以分成 1, 1. 赢当 N = 3 时, 分成 1, 2. 输当 N = 4 时, 分成 2, 2, 赢当 N = 5 时, (1,1,3) (1,2,2) (2,3) 都是输总结1. 稳赢叫做安全局面. 能一步跳到安全局面的叫做不安全局面. 不安全局面都是稳输的2. 安全局面不能直接跳到安全局面, 即安
阅读全文
摘要:题目N 个石头排成一行, 每块石头有固定的位置和编号, 两个玩家依次取石头, 每个玩家可以取其中的任一块石头, 或者相邻的两个石头. 石头在游戏过程中不能移位, 最后将剩下的石头依次取光的玩家获胜思路1. 从简单的特例除法讨论当石头的数目 N = 1,2 时, 先取者胜当石头的数目 N = 3 时, 中间一个, 先取者胜当石头的数目 N = 4 时, 取中间两个, 先取者胜可以发现规律假设 N <= i 时, 先取者胜.当 N(N=i+1) 为奇数时, 取中间一个, 否则取中间两个, 将石子堆成相等的两堆, 两堆的数目小于 i, 对于一堆先取的胜, 两堆就是后取的胜. 得出结论, 先取的
阅读全文
摘要:题目有 n 个学生分别对 m 个见面会感兴趣, 为了满足所有学生的要求, HR 希望每个学生都能参加自己感兴趣的所有见面会思路1. 假设某一个同学同时对k个小组感兴趣, 那么这k个小组两两之间都要有一条边, 这样就转化成了最少着色问题. 图的最少着色问题至今没有有效解法, 可以使用dfs枚举, 时间复杂度很高2. 我们可以尝试对这个图进行K着色, 首先把K设置成1, 看看有没有适合的方案, 再逐渐把K提高. 当假设待求的图最少着色数远小于图的定点数时, 这个算法的复杂度远低于方法(1)扩展问题1. 假设有 N 个面试要同时进行, 他们的面试时间分别是 B[i], E[i]. 我们希望将这N个面
阅读全文
摘要:题目电梯每次上升只停一次, 求问电梯停在哪一楼能够保证乘坐电梯的所有乘客爬楼层的层数之和最小思路假设电梯的层数是 m, 乘客人数是 n1. 枚举, 时间复杂度是 o(mn)2. 滚动解法. 先对 n 名乘客排序, nlogn 然后移动游标, 时间复杂度为 o(nlogn)假设电梯的层数是 n, 要去第 i 层的乘客数目为 tot[i]1. 假设在第 i 层停时, 有 X 人向上爬, Z 人不用爬, Y 人向下走, 需要走的步数之和为 F, 在这个前提下, 电梯在 i+1 层停靠. 那么 F' = F+X+Z-Y. X = X+Z, Y = Y-TOT[i+1]在这种数据结构下, 时间复
阅读全文
摘要:题目给出几条线段, 求解这几条线段把给定平面切成的份数思路1. 枚举 3 条直线的情况, 发现有规律可循两条直线, 一个交点 -> 空间分成 4 份三条直线, 两个交点 -> 空间分成 6 份三条直线, 三个交点 -> 空间分成 7 份即, 份数= 直线数+交点数+12. 题目转化成求解直线的交点数假设直线在左边的从上到下的顺序是 a,b,c, 在右边从上到下是 c,b,aa,0 b,1, c,2那么右边就变成了, 2,1,0求其逆序数就是结果 3
阅读全文
摘要:题目1. 所有的 ID 都出现 2 次, 只有一个例外, 找到那个例外的 ID2. 所有的 ID 都出现两次, 只有两个例外, 找出例外的那两个总计1. 剑指 offer 上有这两道题的解法, 不过那时并没有讨论两个例外ID相同的情况2. 当已知例外的 ID 相同时, 我们需要更多的先验知识, 原始的所有 ID. 然后使用除法或者减法.3. 当不确定例外的 ID 是否相同时, 我们可以先做一步加法, 求得 x+y = a, 还需要一个式子. 这个式子可以使 x*y, 或者 x^2+y^2
阅读全文
摘要:题目书店搞促销, 同时购买多卷书时, 有机会享受优惠2本优惠 5%, 3本 10%, 4 本 20% 5 本 25%设计算法, 求解购买一本书的最低价格分析1. 第一个感觉是一次购买的越多省钱越多, 即贪心的思想, 但这样的思路对不对呢? 考虑下面一个案例购买两本卷一, 两本卷二, 两本卷三, 一本卷四卷五假如按照贪心的思路去求解, 共会花费 51.6 元, 而假如四本四本的买, 仅需 51.2 元, 所以贪心法不一定总是最优解2. 动规解法F(x1, x2, x3, x4, x5) 表示购买 x1 本卷一, x2... 所需的最少钱数稍加分析, 可以得出, F(x2, x1, x3, x4,
阅读全文
摘要:题目假设有这样一个拥有三个操作的队列1. Enqueue(v)2. Dequeue()3. MaxEle()请设计一种数据结构和算法, 让 MAXELE 操作的时间复杂度尽可能的低思路1. 刚看到题, 以为这就是 stack 求 min 的逆过程, 着实是理解有误2. 比较优雅的解法是利用两个堆栈来模拟队列, 模拟的方法以前是做过习题的, 不必多说3. 重点是 stack 的实现. stack 有 4 个私有变量Type stackItem[MAXN]; // store real numbersint stackTop; // point to top of stackint link2Ne
阅读全文
摘要:题目给定字符串 s1 和 s2, 要求判定 s2能否能够被通过 s1 做循环移位得到的字符包含. s1 = AABCD, s2 = CDAA 返回 true. 给定 s1 = ABCD 和 s2 = ACBD 返回 false解法1. 最直接的方法是对 s1 进行移位然后比较. 若 s1 较长, 那么效率较低2. 题目转化成比较 s2 是否在 s1s1 中,这样可以利用 kmp 等算法提高对比效率
阅读全文
摘要:Leetcode 上有连续的两道题, 一个是 insert interval, 一个是 merge interval, 其中 insert interval 是 merge interval. 其中 insert interval 还是 merge interval 的扩展, 即便看起来相反解法1. 先对目标区间进行处理, 先排序后 merge, 时间复杂度为 o(nlogn)2. 使用二分查找, 找到一个区间, 然后看该区间是否包含源区间3. 因为目标区间是非连续的, 所以(2) 只要找出一个区间就好
阅读全文
摘要:解法1. 假设在目标数组 array[] 的前 i 个元素中, 最长递增子序列的长度为 LIS[i]那么状态转移方程为LIS[i] = max(1, LIS[k]+1) array[i+1] > array[k], for any k 2, 就可以直接把 4 加到前面的子序列中形成一个新的递增子序列受此启发, 我们希望找到前 i 个元素中的一个递增子序列, 使得这个递增子序列的最大元素比 array[i+1] 要小, 且长度尽可能的长. 这样将 array[i+1] 加在该递增子序列后, 便可找到以 array[i+1] 为最大元素的最长递增子序列长度为 1 的递增子序列最大元素的最小值
阅读全文
摘要:这道题在算法课上当做例题讲过, 当时的印象也比较深另有一道近似算法的题也在算法课上讲过, 并且印象更深, 复习的时候完全没管, 以为志在必得, 结果真考了那道近似算法, 我却没能打出来为避免阴沟翻船, 寻找最近点对还要再回顾一下算法核心是分治算法1. 分别根据点的 x,y 值进行排序2. 在 x 轴上划一道垂线, 将点均分成两半3. 假设最近点对都在左/右部分, 递归计算左/右半部分的最短距离并返回较小值 dis4. 假设最近点对分别在左右两个部分, 横跨中心的竖线. 中心线为中心, 2*dis 为宽度画一个矩形, 横跨中心线的最近点对 candidate 都在这个矩形内. 将这些点按照 y
阅读全文
摘要:解法1. 设置 min, max 两个变量, 然后遍历一遍数组, 比较次数为 2*N2. 依然设置 min, max 两个变量并遍历数组, 但将遍历的 step 设置为 2, 比较次数为 1.5 * N3. 改变数组的做法. 先排个序使得 min 总是在偶数位置, max 总在奇数位置, 比较次数依然是 1.5*N4. 分值算法, 实际上就是归并算法的变形实现较为复杂, 但事件复杂度依然为 1.5N
阅读全文
摘要:题目任意给定一个正整数 N, 求一个最小的正整数 M (M > 1), 使得 N*M 的十进制表达式中只有 0 和 1.解法1. 枚举0,1能够组成的数字, 可以组成一颗二叉树然后由 BFS 算法最终能够得到目标解. 但时间复杂度太高2. 优化. 考虑对每一个节点加上一个属性, 对 N 求余的值. 假设两个节点X, Y的余相同, 那么由该节点扩展的下一层的 4 个子节点, 分别为 10*X, 10*X+1, 10*Y, 10*Y+1. 由取模的定理知道 10*X MOD N == 10*Y MOD N, 10*X +1 MOD N == 10*Y +1 MOD N假设 X < Y,
阅读全文
摘要:解法1. f(x,y) = f(y, y%x) (y>0) 辗转相除法2. 取模运算较为耗时, 将取模变成相减. 但对极端数据效果很差, 比如 gcd(1000,1)3. 分析公约数的特点. 3.1 若 x,y 均为偶数, 那么 f(x,y) = 2*f(x/2, y/2) 3.2 若 x 为偶数, y 为奇数, 那么 f(x,y) = 2*f(x/2, y) 3.3 若都为奇数, f(x,y) = f(x, x-y) 那么下一步肯定有一个偶数 3.4 这样一来, 时间复杂度下降到 o(log(max(x,y)))
阅读全文
摘要:有限小数和无限循环小数转化成分数比如 0.9 -> 9/100.333(3) -> 1/3解法1. 主要涉及到一个数学公式的计算.2. 对于有限小数, 分子分母求最大公约数即可3. 对于无限循环小数, 第一步是将非循环部分剔除. 仅讨论循环部分.4. 0.b(b.size() = c ==> b.b(b.size()) = c*pow(10, b.size()) ==> 0.b(b.size()) = c*k-c ==> c = (pow(10,b.size()-1)/b
阅读全文