|
d**********x 发帖数: 4083 | 2 一个简洁一点的办法
先用O(V^3)的算法找出all pair shortest paths
设起点为S,终点为T
然后从目标点递归回溯,回溯过程中取点v,使得S到v距离加上v到其下一点u的距离之
和为S到u的距离。大体上如下:
find_path(Vertex source, Vertex target)
static list path
path.push(target)
if source == target
output path
path.pop(source)
return
for Vertex v in t.neighbors
if dist(source, v) + dist(v, target) == dist(source, target)
find_path(source, v)
path.pop(target) |
|
g*****g 发帖数: 34805 | 3 不行用解释几何应该也很容易,设个坐标系算一下一个二维
式子的最小值。 |
|
p******9 发帖数: 47 | 4 不知道对不对
(1) 设A=kC+x, 那么A^B % C = (kC + x)^B % C= x^B % C = (x^(B/2) )^2 % C = (x
^(B /2)%C)^2 = ... O(logn)求得结果
(2) 维护一个堆,每次拿出最小的两个,再把生成的结果放回去,O(nlogn) |
|
b***r 发帖数: 4186 | 5 对啊,问我下面的code有什么错
final hashmap aMap=new hashmap();
aMap=new hashmap();
我说都final乐,不能再assign乐,
他说那会给什么错,
我想了老半天说,我不知道,我的IDE会报错,不会让我compile.
他说对。
晕阿,设套? |
|
b****e 发帖数: 45 | 6 将初始数列设为1..n,然后扫描signature, 碰到“I”就跳过,碰到连续的"D"就翻转
相应位置上的数字。代码如下:
vector FindSmallestPermutation(string signature) {
vector res(signature.size() + 1, 0);
for (int i = 0; i < res.size(); i++) {
res[i] = i + 1;
}
int pos = 0;
int start = 0;
while (pos < signature.size()) {
if (signature[pos] == 'D') {
start = pos;
while (pos < signature.size() && signature[pos] == 'D')
pos++;
reverse(res.begin() + st... 阅读全帖 |
|
f*****e 发帖数: 2992 | 7 有兴趣的话,可以把longway的那个条件语句里设个static variable++试试看。 |
|
d**s 发帖数: 98 | 8 非常规的解法:
http://blog.csdn.net/anchor89/article/details/6055412
经典面试题:设计包含min函数的栈,O(1)空间实现方法
分类: 数据结构和算法 2010-12-04 22:20 2102人阅读 评论(10) 收藏 举报
题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数
min、push以及pop的时间复杂度都是O(1)。
注:这是06年一道Google的面试题.
先来说个常规解和他的一个优化,常规解的时间复杂度符合要求,但需要线性的额外空间.
常规解(参考 http://zhedahht.blog.163.com/blog/static/25411174200712895228171/):
除了题目要求的栈之外新开一个栈,用来记录最小值,每当在原栈中push数据后,与最小
值栈中的栈顶元素比较,如果新值较小,则在最小值栈中push新值;否则再次push栈顶元
素.
pop的时候,只要将最小值栈也pop一下就行了.
这样,min函数只需要返回最小值栈的栈顶元素即可.
常规解空间上的一个优化:
一般... 阅读全帖 |
|
s****t 发帖数: 467 | 9 似乎记得以前在版面上看过,不过找不到了。
题目大意是说给定两个人,需要知道他们是不是genetically related。Genetically
related的定义是指父母子女、兄弟姐妹这样的关系,夫妻关系不属于。问需要怎样设
计family tree/graph来支持这样的查找。
想了半天没想到好的解法,大家有什么想法吗? |
|
K*****k 发帖数: 430 | 10 我自己后来想了下,应该和二爷的思路大体一致,只不过二爷好像是从尾部倒着来,我
的是从头部顺着来。
二爷能否看看对不对。
假如char str[0 .. n - 1]是输入字符串
定义int dp[0 .. n - 1],全部初始化为0
dp[j]表示str[0 .. j]的最小的划分词数,先计算出dp[0]来
求dp[j + 1], 就是
1) 如果str[0 .. j + 1]在字典中,直接设dp[j + 1] = 1
2) 遍历1 <= k <= j + 1, 如果str[k .. j + 1]在字典中且dp[k - 1]大于0,把最小的
那个dp[k - 1]加上1放到dp[j + 1]中
最后的结果就是返回dp[n - 1], 如果值为0表示无法分词。 |
|
m***k 发帖数: 946 | 11 设f(N)为最多可以抛N次的情况下,最大值的期望。
那么显然f(N+1) =
1/6 * 6 (第一次抛点数为6, 不用继续抛了) +
1/6 * max{5, f(N)} (第一次抛点数为5) +
1/6 * max{4, f(N)} (第一次抛点数为4) +
1/6 * max{3, f(N)} (第一次抛点数为3) +
1/6 * max{2, f(N)} (第一次抛点数为2) +
1/6 * f(N) (第一次抛点数为1, 肯定接着抛
;
f(1) = 1/6 (1+2+...+6). |
|
m***k 发帖数: 946 | 12 设f(N)为最多可以抛N次的情况下,最大值的期望。
那么显然f(N+1) =
1/6 * 6 (第一次抛点数为6, 不用继续抛了) +
1/6 * max{5, f(N)} (第一次抛点数为5) +
1/6 * max{4, f(N)} (第一次抛点数为4) +
1/6 * max{3, f(N)} (第一次抛点数为3) +
1/6 * max{2, f(N)} (第一次抛点数为2) +
1/6 * f(N) (第一次抛点数为1, 肯定接着抛
;
f(1) = 1/6 (1+2+...+6). |
|
c********w 发帖数: 2438 | 13 来自主题: JobHunting版 - 请教一道题 另开一个大的数组b
把原来数组a里有的数做大数组的index
b[a[i]]都设为1
其余为0
然后统计?
可以么? |
|
h*******0 发帖数: 270 | 14 可以设linkedlist pointer指向null, loop结束后检查pointer是否指向了null。 如
果指向null了,返回\0。 不过我觉得面试官考的有点无厘头。。。 |
|
w****x 发帖数: 2483 | 15
多分几个数据库是不是可以,这个问题没那么容易啊。
实在不行只有设两个字段或两个数据库,如果出了问题只有互相对比判断到底收钱了没 |
|
l*********8 发帖数: 4642 | 16 设字符串S长度为N。
取K为N的质数因子,然后求解。 |
|
l*****a 发帖数: 14598 | 17 quick select O(n)
设一个pivot,分成两组,根据两组大小然后继续... |
|
y****n 发帖数: 743 | 18 1. 因为对称,计算1/8圆,就可以画整个圆。
2. 设d=x^2+y^2-r^2,当d>0,说明点在圆外
3. 最开始x=r,y=0
4. 下一个点,y++:
因为公式:(y+1)^2=y^2+2y+1,所以d+=2y+1。
如果d>0,则x--,同时d-=2x-1;
5. 重复第四步,直到1/8圆
public void DrawCircle(Bitmap bitmap, int centerX, int centerY, int r)
{
int x = r;
int y = 0;
int diff = 0;
while (x >= y)
{
DrawPixel(bitmap, centerX + x, centerY + y);
DrawPixel(bitmap, centerX - x, centerY + y);
DrawPixel(bitmap, centerX + x, centerY - y);
DrawPixel(bitmap, centerX - x, centerY - y);
DrawPixel(bitmap, centerX + y, centerY + x... 阅读全帖 |
|
f**********t 发帖数: 1001 | 19 我有一个M*N维的矩阵
希望找到一个m*n维的子矩阵使得其元素和最大
这个子矩阵的行和列不一定要连续
这个问题有好的解么?
就比如说,一个矩阵是3*3的
设每行每列的编号是(1, 1,) (1, 2), (1, 3)(2, 1,) (2, 2), (2, 3)(3, 1,) (3, 2)
, (3, 3),则(1, 1)(1, 3)(3, 1)(3, 3)这四个点组成的也算是个子矩阵
目前有想法,但时间复杂度很大。感觉好像只有枚举法来做这个问题。不知大家有没有
更好的解法。 |
|
w***y 发帖数: 6251 | 20 遇到挡板就停下来
我想最后跟迷宫解法是没区别的, 但是这个是设计提, 最主要的是用什么样的class/
structure去组织。 当时面试官花了很多时间问我,想要用什么去表示这个迷宫---
传统的就是一个array; 剩下的就是用到哪些method什么的,譬如移动一下到什么位
置怎么实现之类的 |
|
b******7 发帖数: 92 | 21 不能先分段shuffle,再shuffle段id,这样不均匀。比如考虑数组为aaaaabcdef,若按
照这个思路,则无论怎么shuffle,这5个a都会在一起。
我的考虑和racolas一样,先将N个元素shuffle到M个文件中,再在M个文件内shuffle,
最后合并。
定义每个文件当前可容纳元素个数r[i],i=0...M-1,初始时所有r[i]都为N/M
从磁盘上读取N个元素,设当前为第k个元素,则根据rand[1,N-k]落入{r[0],r[0]+r[1]
,r[0]+r[1]+r[2],...}中的哪一个决定第k个元素写入哪个文件,并且相应的文件可容
纳个数减1。 |
|
b******7 发帖数: 92 | 22 4)
设两人概率分别为p1,1-p1
则p1 = 1/6 + 5/6 * (1-p1) ==> p1 = 6/11, 1-p1 = 5/11
5)
判断顺子:将7张牌按数字排序,然后遍历找是否有连续的5个数字
判断同花:将7张牌按花色排序,然后找是否有连续的5个花色
判断同花顺:将同花中的最多连续的花色按数字排序,找连续5个数字
6)
构建trie,trie节点中加一个计数变量,统计多少个url包含该trie节点,然后按层遍
历+减枝找到最长的prefix
struct TrieNode{
char c;
vector childs;
int count;
}; |
|
b******7 发帖数: 92 | 23 设A、B两人概率为Pa,Pb
则A获胜有两种可能:
1.A第一次就kill了B,概率为1/6
2.A第一次没有kill掉B(5/6的概率),但接下来的轮到B先开始的回合里,B没有获胜(
1-Pa的概率),总概率为5/6*(1-Pa)
Pa = 1/6 + 5/6 * (1- Pa) |
|
r**a 发帖数: 31 | 24 你的方法实现起来简单,当m和n有一个很小时非常实用
更通用的做法是解一个线性方程组(mod 2意义下的),一共有m*n个方程和m*n个未知数
,每个未知数表示这个灯泡是否需要变化,每个方程表示一个灯泡的情况。举例来说,
设2*2的灯泡的情况是
V00 V01
V10 V11
这里Vij取值为0或1,表示灯泡一开始亮或灭。有方程组
X00 + X01 + X10 = V00
X00 + X01 + X11 = V01
X00 + X10 + X11 = V10
X01 + X10 + X11 = V11
在mod 2意义下解这个方程组就可以了。用直接的高斯消元法,复杂度是O((m*n)^3)。
因为这里方程组的系数非常有规律,实际上好像有更快的做法。 |
|
j******i 发帖数: 244 | 25 设从(0, 0)到(i, j)的最小和为P(i, j)
P(i, j) = min(P(i - 1, j), P(i - 1, j - 1)) + triangle[i][j] (除了边界上的
点)
这样知道上一行的P值,就可以推出下一行的P值,找出最后一行P值的最小值返回即可。
时间O(n^2),空间O(n)
class Solution {
public:
int minimumTotal(vector > &triangle) {
int n = triangle.size();
int * p = new int[n]();
int * q = new int[n]();
for (int i = 0; i < n; ++i) {
p[0] = q[0] + triangle[i][0];
for (int j = 1; j < i + 1; ++j) {
if (j == i)
... 阅读全帖 |
|
a******e 发帖数: 710 | 26 我想到一个小改进,利用三角不等式,即三角形两边之差<=第三条边的长度
两个字符串看成两个向量: B 和 C, C是A的子串。
现在要找距离B最小的C。
我们设三角形的第三点为原点O, 这样d(B,O)的距离就固定了,d(C,O)的距离可以在O(
1)时间内得到,因为d(C,O)就是各个字符的平方和。
根据三角不等式,我们有
d(B,C)>= abs( d(B,O) - d(C,O) )
其中右半部分部分可以在O(1)时间内得到。 如果算出来的这个d(B,C)的下限比目前的
最小距离还大, 那么这个C显然不可能是最近的子串,就不用再去计算d(B,C)了。
此思路与rolling hash有相似之处,只不过效率稍逊rolling hash,因为好的hash
function可以大幅减少collision
如A |
|
f********4 发帖数: 988 | 27 如果你同意sum >= 0是有解的,而且题目说了是唯一解。那么你找到的那个index,从
这个index出发,一直到array的尾部,每一项subSum都是大于0的,这个你肯定同意,
如果不是的话,就不会返回这个index。那么接下来就到了这个index的前半部分,你怎
么证明前半部分每一项subSum 都是大于0的,因为如果每一项大于0,那index就是解。
假设前面加到某一项的时候,设为index1,subSum小于0了,那根据sum大于等于0,也
就是说从这之后的subSum加起来是大于0的(因为从index到array的尾部一直到index1相
加的subsum是小于0的,满足sum大于0,index1到index之间的subsum一定大于0)。那么
这样index1就会成为index那个返回的点,因为index1不是index,所以没有这样的点。 |
|
e******g 发帖数: 51 | 28 上周电面遇到的,
给定一个Robot,这个robot有个lazy的探测器,可以探测自己和某个人(设为A)的距离。
现在A的状况未知,可能静止,也可能无规律地行走或奔跑,
问怎样设计策略(或算法)能尽快追上A。(假定robot和A在一个平面上)
求问各位大神有什么好的方法?
能不能让robot匀速运动然后计算相对加速度曲线? |
|
A*********c 发帖数: 430 | 29 来自主题: JobHunting版 - 上一道小题 想了一下,好像比想象的复杂,case比较多,关键是进位比较麻烦。
还写不出代码,胡说一下讨论讨论。
从任意数字生成palindrome比较复杂,
先假定输入已经是palindrome,生成下一个palindrome,因为这个可以解决第二个以后
的数字
给定任意一个palindome,设两个index,都放在中间。
如果是奇数位aaaxbbb, i,j 都指x
如果是偶数位aaxxbb,则i指第一个x,j指第二个。
最接近的下一个数字就是就是把x+1。如果x是9,就把x置零,对i-1,j+1加1
如果生成的最终数字多了一位如9999->10000, 就把个位数再加1.
现在就是怎么生成第一个palindrome,这个可以考虑用暴力,那就比较简单了。
如果不暴,是不是也可以用相似的双指针想法。但是好像情况比较复杂。
abcd efgh,还是俩index i j,从两边往中间扫。s[j] < s[i], 就把
s[j]变s[i],如果s[j] > s[i] ,还是s[j]变s[i],但是要把s[j-1], s[i+1]加一。
思路好像不是很elegent. 先走,有空再想想。 |
|
t****d 发帖数: 89 | 30 一个double类型的array名为list,长度为n,设两个点i和j,0
i],list[i+1]到list[j],list[j+1]到list[n]分别算一个score。需要找到i,j两个点,
使得三段的score之和最小。请问有什么好的算法,使得time complexity最小? |
|
s********u 发帖数: 1109 | 31 就是优先看斜率,再看截距。比较函数要注意严格弱序。只要定义了严格弱序,那么“
=”就相当于 非'a
我本来想用系统自带的epsilon,但可能太小了,反而失败了。就随便设了0.000001 |
|
D**********d 发帖数: 849 | 32 觉得可以直接计算而不用 blue force.
思路以例子说明:
assume: XXX123XX
1. 计算每位对 13 的余数,如 1%13 = 1, 10%13= 10, 100%13 = 9 ... etc.
2. 计算在高位余数 i = 0,...,12 时,XX 出现的余数为 3 的个数,e.g. XXX12300
余 0 时,XXX12300 -- XXX12399 间余数为 3 的数的个数是 99/13 = 7 ... 8, 所以
有 7 个。a_0 = 7
3. 利用 (1) 中结果计算 XXX123.. 高位 %13 余数 为 i = 0,...,12 的个数。设为 b
_i,
4. 总个数 \sum_0^{12} a_i * b_i |
|
a*********2 发帖数: 194 | 33 DP?
假设初设strength为0,然后找从左上到右下角的最大strength。
结果路径最大,那么中间每一步都最大。
所以 f(i,j) = max( f(i-1,j), f(i,j-1) ) + grid(i,j) .
初始值f(0,1)=grid(0,1), f(1,0)=grid(1,0),从(0,0)算到(n-1,m-1). |
|
c*******7 发帖数: 438 | 34 大概想了下,感觉DP的话每个格要保留的数据需要挺多才能不丢失信息。
设第一格为零,第一格开始做DP,每个格保留一个list,list里每个元素为某条路径的
当前体力值和路径最小体力值,list按照路径最小体力值排序。计算某一格新的list的
时候,merge左边格子和上面格子的两个list,去掉路径最小体力值小且当前体力值小的
元素。
到最后一格的时候找到当前体力值大于等于零且[路径最小体力值]的最小值 |
|
X*4 发帖数: 101 | 35 这个好复杂
其实可以优化armstrong12的方法
假设初设strength为0,然后找从左上到右下角的最大strength。
结果路径最大,那么中间每一步都最大。
所以 f(i,j) = max( f(i-1,j), f(i,j-1) ) + grid(i,j) .
初始值f(0,1)=grid(0,1), f(1,0)=grid(1,0),从(0,0)算到(n-1,m-1).
这个方法的问题在于 能保证 任何时刻如果你的strength > 0
先看一维的情况
-5 1 -3
armstrong12方法给出的结果 f[n-1] = grid[n] + f[n-1], 从后往前
f = [-7, -2, -3], 有的地方strength < 0, 所以不对
改进, 增加一个数目m, m[i]表示进入grid[i]之前需要的最小strength
grid[2] = -3.
所以要想保证 每步strength > 0, 进入grid[2]之前, strength 至少 > 3
m[i] = 3,
f = [,,0]
m = [,,3]
grid[1] = 1, 根据公式
f = [,... 阅读全帖 |
|
x***z 发帖数: 89 | 36 正整数1到n,随机排列成一个元素数为2n的数列,其中1到n各出现两次,
出现位置随机,设正整数k,k大于等于1,小于等于n,问k第一次出现在数列
第一位,第二位,第三位。。。。最后一位的概率分别是多少?
其实,就是在该数列中查找k,求平均查找次数 |
|
SX 发帖数: 178 | 37 IE 都好意思问你是不是要把它设成默认浏览器呢!
赞这句! |
|
y*****h 发帖数: 22 | 38 patternPos表示从哪里开始匹配。初始值为0。
patternEnd表示模式结束的位置。初始值为0。
当前字符和patternPos不相等的话,说明pattern不成立,patternPos回到开始位置0,
patternEnd设为当前字符所在位置i。
当前字符和patternPos相等的话,patternPos加1移到下一个位置,patternEnd保持不
变。并检查下如果patternPos超过patternEnd的话,说明截止到当前字符成功匹配,
patternPos回到开始开始匹配下一串字符。注意,当i走到最后的话,patternPos就不
用清0了。
最后判断成功的条件是,patternPos大于patternEnd的时候,说明整个字符串pattern
且至少重复pattern两次。patternEnd大于零,说明pattern长度大于1。 |
|
l********e 发帖数: 3 | 39 这是我的思路,
1)假设输入字符串是s1, 长度为 N, 我们要找的重复的短字符串为result
2)一开始把result 设成s1的前两个字符。
3)引入两个索引变量i,j,i指向s1的字符,j指向result的字符。i=2, j=0
4)检查 s1[i] == result[j],如果成立,则j++;否则的话说明出现了mismatch,说明
result可能太短,需要扩展。扩展的字符应该是 s1[i-j,i],把这个扩展追加到result,
并且把j设置成0。
5)循环结束后检查result的长度和j是否相等,如果相等的话说明满足要求。当然还要
进一步确定result.size() == s1.size(),如果相等说名没有重复,返回false。
以下是不太严谨的的代码,
#include
#include
#include
#include
using namespace std;
bool isRepeated(string s1) {
size_t N = s1.size();
strin... 阅读全帖 |
|
l********e 发帖数: 3 | 40 这是我的思路,
1)假设输入字符串是s1, 长度为 N, 我们要找的重复的短字符串为result
2)一开始把result 设成s1的前两个字符。
3)引入两个索引变量i,j,i指向s1的字符,j指向result的字符。i=2, j=0
4)检查 s1[i] == result[j],如果成立,则j++;否则的话说明出现了mismatch,说明
result可能太短,需要扩展。扩展的字符应该是 s1[i-j,i],把这个扩展追加到result,
并且把j设置成0。
5)循环结束后检查result的长度和j是否相等,如果相等的话说明满足要求。当然还要
进一步确定result.size() == s1.size(),如果相等说名没有重复,返回false。
以下是不太严谨的的代码,
#include
#include
#include
#include
using namespace std;
bool isRepeated(string s1) {
size_t N = s1.size();
strin... 阅读全帖 |
|
l********e 发帖数: 3 | 41 这是我的思路,
1)假设输入字符串是s1, 长度为 N, 我们要找的重复的短字符串为result
2)一开始把result 设成s1的前两个字符。
3)引入两个索引变量i,j,i指向s1的字符,j指向result的字符。i=2, j=0
4)检查 s1[i] == result[j],如果成立,则j++;否则的话说明出现了mismatch,说明
result可能太短,需要扩展。扩展的字符应该是 s1[i-j,i],把这个扩展追加到result,
并且把j设置成0。
5)循环结束后检查result的长度和j是否相等,如果相等的话说明满足要求。当然还要
进一步确定result.size() == s1.size(),如果相等说名没有重复,返回false。
以下是不太严谨的的代码,
#include
#include
#include
#include
using namespace std;
bool isRepeated(string s1) {
size_t N = s1.size();
strin... 阅读全帖 |
|
d****n 发帖数: 12461 | 42 来自主题: JobHunting版 - 请教一道题 无非就是f(m,n,p)=max{f(m-1,n,p)+a[m-1],f(m,n-1,p)+b[n-1],f(m,n,p-1)+c[p-1]}
然后设好初始条件就可以了。 |
|
x*******9 发帖数: 138 | 43 设n个string,每个string有m个单词。
最暴力的方法不就是n**2次比较,每次比较的时间复杂度为O(m)
所以总时间复杂度为O(n**2 * m)
LS大大们说的方法貌似没有超过这个纯暴力的吧。。。 |
|
j**********3 发帖数: 3211 | 44 这样,是不是直接设一个boolean值更直接?
感觉不是在这个上边做文章,隐隐约约觉得应该用其他data structure,比如array或
者list什么的实现。。。
但。。。完全没思路啊。。。
. |
|
j**********3 发帖数: 3211 | 45 就是说,设一个boolean值,然后clear了,这个map就不valid了?然后再查它,就不
valid了,那clear了之后,再想往里边塞东西怎么办呢? |
|
j**********3 发帖数: 3211 | 46 这样,是不是直接设一个boolean值更直接?
感觉不是在这个上边做文章,隐隐约约觉得应该用其他data structure,比如array或
者list什么的实现。。。
但。。。完全没思路啊。。。
. |
|
j**********3 发帖数: 3211 | 47 就是说,设一个boolean值,然后clear了,这个map就不valid了?然后再查它,就不
valid了,那clear了之后,再想往里边塞东西怎么办呢? |
|
a***e 发帖数: 413 | 48 第一次看到的时候没想到要push数组的位置,而不是push‘(’,结果怎么都做不出来。
后来看了讨论的idea是把Indices存起来,按照那个想法写了,却发现last的初值要设
成-1,而不是0。最后通过的答案,看着觉得好郁闷,想了好久。。。。。。。
int longestValidParentheses(string s) {
vector left;
int n=s.size();
int last=-1,lmax=0;
for (int i=0; i
{
if (s[i]=='(')
{
left.push_back(i);
}
else if (s[i]==')')
{
if (left.empty())
{
... 阅读全帖 |
|
a*****y 发帖数: 22 | 49 我有一个想法:
先建立map存储价格:(设商品用id表示)
struct ItemPrice {
std::vector items;
int price;
};
std::map > item_prices_;
表示将某个商品映射到所有包含该商品的组合或单件商品的价格
所求:
std::map< std::set, int > min_price_;
int FindMinPrice(const std::set& items, const std::set& used_items
) {
std::set target;
// target = items - used_items
if (target.empty()) {
return 0;
}
if (min_prices_.count(itesms) > 0) {
return ...;
}
int min = 0x7FFFFFF;
// get the first... 阅读全帖 |
|
g*****g 发帖数: 34805 | 50 这个有点简单,就是C*每个用户一行把看过的东西都写进去就行了,时间是colum name
, 东西的key是column value。还可以设个时间超过某个时间的就TTL自动去掉了。当然
A家用的是Dynamo. Cache这个没啥意思,不是明显的cache case. |
|