算法题个人思路总结

1.设A与C是互质的两个数,求B,使得A*B=1(mod C)。

解:由于gcd(A,C)=1,因此利用扩展欧几里德函数可以找到a*A+c*C=1,即a*A=1(mod C)。我们取B=a即可。

2.求$\sum_{i=1}^n{\frac{1}{i}}$的上下界。

解:$\ln \left( n+1 \right) \le \int_1^{n+1}{\frac{1}{x}dx}\le \sum_{i=1}^n{\frac{1}{i}}\le 1+\int_1^n{\frac{1}{x}dx}=1+\ln \left( n \right) $。

3.求形如$\sum_{i=1}^n{i^{\alpha}}$的上下界,其中α>=0。

解:$1+\frac{1}{\alpha +1}\left( n^{\alpha +1}-1 \right) =1+\int_1^n{x^{\alpha}dx}\le \sum_{i=1}^n{i^{\alpha}}\le \int_1^{n+1}{x^{\alpha}dx}=\frac{1}{\alpha +1}\left( \left( n+1 \right) ^{\alpha +1}-1 \right) $。

4.要求大批量查询区间最大值最小值,区间不会被修改。

解:使用ST算法在长度为n的区间上以时空复杂度O(nlog2n)做预处理,并以O(1)时间复杂度做查询。

5.在一株树上统计路径信息。

解:使用LCT,所有操作时间复杂度均为O(log2n)。

6.数据范围较大,但实际数据较少。

解:离散处理。

7.要求多次处理树上差分,每个结点对应一组值。

解:树上每个结点对应一个持久化线段树,并且子结点的持久化线段树在父结点的持久化线段树上创建。

8.给定n大小不变区间,区间值最大值为k,m次查询区间第k小。

解:将区间视为一株树,下标i对应i+1的父结点,问题相当于在树上做差分。查询区间[l,r]上第k小,等价于查询持久化线段树r与持久化线段树l-1的差分对应的线段树上第k小元素。时间复杂度为O((n+m)log2(k))。

9.给定一株含n个结点的树,m次查询lca。

解:1.先利用dfs将树压成区间,之后利用st处理区间最小值和最大值。时间复杂度为O(2nlog2(n)+m)。

  2.如果允许离线处理,则利用tarjan算法可以在O(n+m)时间复杂度内求出。

10.给定长度为n的字符串,m次判断两个子串是否相同。

解:在字符串上进行hash处理,之后以O(1)实际复杂度取子串哈希值并进行比较。实际复杂度为O(n+m)。注意要小心生日悖论,如果哈希范围为k,则只需要sqrt(k)个不同子串就有1/2以上的概率使得存在两个子串拥有相同哈希值,这时候可以多次进行哈希,从而提高k的范围。

11.平面上n个矩形,求被这些矩形覆盖的面积。

解:先对矩形按照矩形底部y坐标进行从小到大排序。之后用扫描线算法从左到右扫描矩形左右边界。总的时间复杂度为O(n^2)。

原文地址:https://www.cnblogs.com/dalt/p/9173085.html

时间: 2024-08-01 21:30:00

算法题个人思路总结的相关文章

leetcode链表算法题实现思路

找出两个链表的交点(leetcode160) 一条链表遍历完之后跳转到下一条链表的头节点继续遍历.  因为当两条链表均被遍历一遍以后,第二次遍历时会同时到达节点相等的地方.如果没有相交的节点,两条链表均遍历两遍后,同时等于null,故返回null. public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode l1 = headA, l2 = headB; while (l1 != l2) { l1

记一道毫无思路的算法题

今天贤内给了我一道很实际的算法题,把我彻底难住了,实在想不出来,于是写此博文以记之. 背景是这样的,现在有一个付款明细的Excel,里面有为哪个发票,哪个公司应付多少钱的明细,明细数据是62条,现在知道我们已经付出的金额为Sum,请问到底哪些发票是已付款的. 这是62条明细数据: 653165.00 356029.11 220896.45 146362.00 1847670.00 3018518.91 1347553.07 145010.74 339784.84 199350.28 120611

算法题——翻转链表中的一段

题目:给出一个链表中的两个指针p1和p2,将其之间的结点翻转. 思路:可以通过交换结点内的值来实现结点的翻转,空间为O(N):如果要求不能交换值,那么仅凭p1和p2是无法翻转的,只能交换两个指针之间的链表. 代码: 交换值: 1 struct ListNode 2 { 3 int val; 4 ListNode *next; 5 }; 6 7 void reverseNodes(ListNode *p1, ListNode *p2) { 8 if ( p1 == NULL || p2 == NU

一天一道算法题--6.25--无定义

感谢微信平台---一天一道算法题--每天多一点进步---- 其实今天我接下去补上的几题都来自---待字闺中 所以我就原封不动的将它的题目与分析搬过来了 原题 给定一个数组,我们可以找到两个不相交的.并且是连续的子数组A和B,A中的数字和为sum(A), B中的元素和为sum(B).找到这样的A和B,满足sum(A) - sum(B)的绝对值是最大的. 例如:[2, -1 -2, 1, -4, 2, 8]划分为A=[-1, -2, 1, -4], B=[2, 8], 最大的值为16 分析 如果没有

一道看似非常难的面试算法题

这是昨天面试百度时碰到的一道算法题:任意数分三组,使得每组的和尽量相等.由于时间仓促,加之面试时头昏脑涨,这道题没做出来甚至没有给出思路,这让我多少有些遗憾和不甘.因为最近接触算法的东西较多而且本身对算法感兴趣,所以回家之后绞尽脑汁想把这题做出来.其实刚看到这题时感觉不难,但是因为数字个数及数值的不确定,我感觉这题越想越难.昨天一晚上没有睡好,甚至做梦都在想这题! 今天上午在多个群里问了这题,都没有给出思路,真是绝望至极.很多人都说 n/3 的思路,其实这种思路一开始就是死胡同.本人属于那种不会

FCC上的javascript算法题之中级篇

FCC中的javascript中级算法题解答 中级算法的题目中用到了很多js的知识点,比如迭代,闭包,以及对json数据的使用等等,现在将自己中级算法的解答思路整理出来供大家参考讨论.欢迎大家提出新的思路,写出更简单的解法. 1.给一个包含两个数字的数组.返回这两个数字和它们之间所有数字的和. 说明:最小的数字并非总在最前面 如:sumAll([4, 1]) 应该返回 10. sumAll([5, 10]) 应该返回 45. function sumAll(arr) { var max=Math

算多题解题思路

根据自己刷过的算法题,一般通过如下思路解决: 1,最常见的就是字符串处理: 2,常见的排序算法: 3,二分查找: 4,双指针: 5,位处理: 6,回溯算法: 7,动态规划: 8,不仅仅要考虑代码的功能性(对正确的输入能有真确的输出),还要考虑代码的鲁棒性(能够处理错误的输入,而不会导致程序的崩溃) 鲁棒性:如对于链表,输入空链表,输入链表只有一个节点等等: 9,能用递归的基本都能用迭代:

算法题——归并排序的原地实现

普通的归并排序,需要一个额外的数组来保存每次merge的结果:如果要求不使用额外空间,那么每次merge的时候需要做一些处理. 思路: 合并left[] 和 right[]时,假如right[0]应该放入left[3],那么:①可以用一个var来保存right[0],然后将left[3]之后的元素右移一次,再将var值放入left[3]:②也可以交换right[0]和left[3]的值,然后left[0]在新的位置向后遍历,找到合适的位置,再把前面的移位.    寻找合适位置的过程是一次插入排序

算法题——数组内有序对的最大距离

题目:给定一个数组A,对于下标i < j,有A[i] < A[j],求j - i 的最大值. 思路:先正序遍历一次,利用一个辅助数组,记录每个元素的左边子数组中最小值的下标:然后倒序遍历,维持两个指针,初始都指向最后一个元素,通过移动两个指针,找出最大距离. 代码: 1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 int maxDist(int num[], int n) 6 {