输入两个链表,找出它们的第一个公共结点。
当不存在公共节点时,返回空节点。
样例
给出两个链表如下所示:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
输出第一个公共节点c1
1 | /** |
输入两个链表,找出它们的第一个公共结点。
当不存在公共节点时,返回空节点。
样例
给出两个链表如下所示:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
输出第一个公共节点c1
1 | /** |
建立秩序,省却搜索。—德国谚语
计算机解决问题,就靠搜索。 而通过建立秩序,可以让计算机更聪明的完成搜索。
而这里的建立秩序,就包括:
两大类存储引擎:
日志结构(log-structured) 的存储引擎,以及面向页面(page-oriented) 的存储引擎(例如B树)。
SSTable
排序字符串表(Sorted String Table)
一般ACM或者笔试题的时间限制是1秒或2秒。
在这种情况下,C++代码中的操作次数控制在 $10^7$ 为最佳。
下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择:
n≤30 => 指数级别, dfs+剪枝,状态压缩dp
n≤100 => $O(n^3)$,floyd,dp,高斯消元
n≤1000 => $O(n^2),O(n^2logn)$,dp,二分,朴素版Dijkstra、朴素版Prim、Bellman-Ford
n≤10000 => $O(n*\sqrt{n})$,块状链表、分块、莫队
n≤100000 => $O(nlogn)$ => 各种sort,线段树、树状数组、set/map、heap、拓扑排序、dijkstra+heap、prim+heap、spfa、求凸包、求半平面交、二分、CDQ分治、整体二分
n≤1000000 => $O(n)$, 以及常数较小的 $O(nlogn)$ 算法 => 单调队列、 hash、双指针扫描、并查集,kmp、AC自动机,常数比较小的 $O(nlogn)$ 的做法:sort、树状数组、heap、dijkstra、spfa
n≤10000000 => $O(n)$, 双指针扫描、kmp、AC自动机、线性筛素数
n≤$10^9$ => $O(\sqrt{n})$, 判断质数
n≤$10^{18}$ => $O(logn)$, 最大公约数,快速幂
n≤$10^{1000}$ => $O((logn)^2)$, 高精度加减乘除
n≤$10^{100000}$ => $O(logk×loglogk)$,k表示位数, 高精度加减、FFT/NTT
猜出一般步骤
证明选择的策略是否是正确的
问题描述:给定N个区间[a,b],取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以重复)
本质:取尽可能的点,使他们可以穿过所有的区间。
解法:
按照右端点排序
枚举区间,选择区间的右端点作为候选集(显然最右边是局部最优解)
1 |
|
类似于选课,课程有交集,我们需要选择最多的课程,使得课程之间没有时间冲突。
本质:选择尽可能多的区间,使他们没有任何重合。
按照右端点排序
枚举区间,选择区间的右端点作为候选集(显然最右边是局部最优解)
如果我多选择一个区间,就会出现相交;
1 | int main(){ |
给定N个闭区间,请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。 输出最小组数。
本质:对区间进行分组,组内无交;极限思考:每一个区间一组是满足条件,但是组数太多;
例题:
主持人调度(每一个主持人不能主持两场节目,使主持人最少)
排序 + 利用小根堆来动态维护最大值(max_r)
top()返回最小的最大值,既然最小的都有交集,更大的就更不用说啦。
1 |
|
给定 N 个闭区间 [ai,bi] 以及一个线段区间 [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。
输出最少区间数,如果无法完全覆盖则输出 −1。
本质:多个区间都能够覆盖某个start位置,我应该选择哪一个呢?
1 | #include <iostream> |
1 | typedef pair<int, int> PII; |
数字以0123456789101112131415…的格式序列化到一个字符序列中。
在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数求任意位对应的数字。
样例
输入:13
输出:1
1 |
|
给定n,将1,2,,n按字典序排列,求第k大的数
实现函数double Power(double base, int exponent),求base的 exponent次方。
不得使用库函数,同时不需要考虑大数问题。
注意:
不会出现底数和指数同为0的情况
当底数为0时,指数一定为正
样例1
输入:10 ,2
输出:100
样例2
输入:10 ,-2
输出:0.01
1 | class Solution { |
请你写一个函数StrToInt,实现把字符串转换成整数这个功能。
当然,不能使用atoi或者其他类似的库函数。
样例
输入:”123”
输出:123
注意:
你的函数应满足下列条件:
忽略所有行首空格,找到第一个非空格字符,可以是 ‘+/−’ 表示是正数或者负数,紧随其后找到最长的一串连续数字,将其解析成一个整数;
整数后可能有任意非数字字符,请将其忽略;
如果整数长度为0,则返回0;
如果整数大于INT_MAX(2^31 − 1),请返回INT_MAX;如果整数小于INT_MIN(−2^31) ,请返回INT_MIN;
我们先遍历一遍,找到字符串的长度,从而得出最高位的权重(10的几次方?)
然后再遍历一遍,进行累加计算。
时间复杂度:$O(2n)$
我们可以在一遍搞定,每遍历到一个新的元素,需要做的步骤是:
(1) sum *= 10
(2) sum += NewElement
新的时间复杂度:$O(n)$
该题目其他部分无非就是模拟了,做模拟题目的时候切记思路清晰。
1 | class Solution { |
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
例如输入数组[3, 32, 321],则打印出这3个数字能排成的最小数字321323。
样例
输入:[3, 32, 321]
输出:321323
注意:输出数字的格式为字符串。
1 | class Solution { |