程序员进阶之算法练习(十七)

前言

正文6道题目来自leetcode––为求职为生的编程网站,目的是工作闲暇之时锤炼代码功底。
如何从这篇文章受益?

先看题目大意,对照Example的样例理解题目意思;
尝试解答,得到自己的答案,并分析时间和空间复杂度
思考完毕,看题目解析,对比分析自己解法的异同和优劣。

题目大都是LeetCode的hard难度。

正文

41.First Missing Positive
题目链接
题目大意:
给出一个数组,找到数组中没有的最小正整数。
要求:O(N)的时间和O(1)的空间复杂度;

Example
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

** 题目解析:**
先不考虑题目要求的时间、空间复杂度;
暴力的做法有两个:
1、时间最快,空间不限:数组a[N],然后出现数字k就a[k]=1标志出现;
2、时间、空间都不限:排序,遍历一遍数组;

回到题目的要求,时间复杂度要求是O(N),可以肯定是会用到方法1;
现在要求O(1)的空间复杂度,那么就必须利用上给出的数组。
遍历数组,如果数字k小于n且非负,那么a[k-1]=k-1;
然后遍历一遍,a[i] != i的就行是解。

** 复杂度解析:**
O(N)的时间和O(1)的空间复杂度;
** 其他解法:**
基数排序。

从低位开始,
当前第i位,统计0出现x次,1出现y次,(x+y == n)
再次扫描数组,可以直接确定每个数字该排在哪里。
if bit = 0 then
idx = total_y + (total_x-left_x)
....
基数排序解法

45. Jump Game II
题目链接
**题目大意: **
给出一个数组,数组上的值表示能前进的距离;
现在从pos=0的位置向右出发,问最少需要走几步才能到达终点。

Example
输入 A = [2,3,1,1,4]
返回 2
因为可以从pos=0走到pos=1,然后直接到达pos=4;

题目解析:
第一反应就是bfs,但是bfs需要每次判断距离[i+1, i+k]内的点是否访问,导致时间复杂度是O(N^2);
这个题也可以用动态规划:
dp[i]表示到达i的最短步数;
那么状态方程可以写成dp[i+k]=min(dp[i+k], dp[i] + 1); k∈[1, nums(i)]
这样对于每个i都需要去更新后面nums[i]状态,故而复杂度也是O(N^2);
对状态转移方程稍作修改:
dp[i] = min(dp[i], dp[k] + 1); k+num[k] >= i 且 k < i
这样可以建一个dp[i]的优先队列,先按照步数排序,再按能到达的距离排序;
每次从队列的顶端拿出步数最小的dp值,判断pos的有效区间是否覆盖当前位置i;
如果不覆盖,那么对i+1必然也不覆盖,可以丢弃;
如果覆盖,则直接dp[i]=dp[k]+1,并把(dp[i],i+nums[i])放入优先队列;
复杂度是O(NlogN)。

提交后,非常遗憾的收获TLE...

仔细观察dp[i]的性质,可以得出一个结论:
步数越大,能到达的距离就越远;
那么先建一个队列,保证步数最小的在前面,后面是步数大但是覆盖距离较远的备选;
这样可以O(1)取出最优解;
并且可以设定一个maxRight,表示队列当前最远的覆盖距离,如果没有大于这个数字,可以不用放入队列;
这样可以在O(N)的时间/空间复杂度解决问题。

** 复杂度解析: **
O(N)的时间/空间复杂度解决问题。

84. Largest Rectangle in Histogram
题目链接
** 题目大意:**
给出一个数组,数组a[i]表示第i栋楼的高度;
求出最大矩形的面积。

example,
Given heights = [2,1,5,6,2,3],
return 10。

样例的图
最大的面积

题目解析:
维护一个高度不减少的栈,每次可以通过栈,快速得出面积。

** 复杂度解析:**
时间复杂度是O(N)
空间复杂度是O(N)

** 代码量:**

int largestRectangleArea(vector<int>& heights) {
        int ret = 0;
        heights.push_back(0);
        stack<int> s;
        for (int col = 0; col < heights.size(); ++col) {
            while (!s.empty() && heights[col] < heights[s.top()]) {
                int top = s.top();
                s.pop();
                int area = heights[top] * (s.empty() ? col : (col - s.top() - 1));
                ret = max(ret, area);
            }
            s.push(col);
        }
        return ret;
    }

85. Maximal Rectangle
题目链接
** 题目大意:**
给出一个01矩阵,求全为1的最大的矩形的面积;

For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.

最大面积如上,为6

** 题目解析:**
假设最后的矩形是(i, j)到(x, y),01矩阵为n*m矩阵;
从1到n枚举y,那么要求变成矩形贴着底边,然后面积尽可能大。
把与底部连着的1统计起来,例如当row=3的时候,分别为[3,1,3,2,2];
此时,题目与84. Largest Rectangle in Histogram完全一致;
维护一个高度不减少的栈,每次可以通过栈,快速得出面积。

** 复杂度解析:**
时间复杂度是O(N)
空间复杂度是O(N)

97. Interleaving String
题目链接
题目大意:
给出三个字符串s1,s2,s3;
判断字符串s3能否由字符串s1和s2组成,要求s1的字符串内字符的相对顺序不变,s2同理。(假如s1=abc,那么在s3中,就不能变成bac,相对顺序必须是abc)

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.

** 题目解析:**
动态规划。
dp[i][j] 表示s1的前i个字符,s2的前j个字符,组成的字符串是否为s3的前i+j个字符。
dp[0][0]=true,表示初始状态。
假设dp[i][j]=true,那么表示s1的前i个字符,s2的前j个字符,与s3的前i+j个字符是匹配的。
那么只要s1[i+1]==s3[i+j+1],那么dp[i+1][j]=true;
同理,有dp[i][j]=true && s2[j+1] == s3[i+j+1] => dp[i][j+1]=true

最后看dp[n][m]是否为true即可。

** 复杂度解析:**
时间和空间复杂度是O(NM) N是s1长度,M是s2长度;

*** 135. Candy ***
题目链接
** 题目大意:**
n个人排成一行,每个人有一个rating的数值。
现在给所有人分配糖果,要求:
1、每个人至少有一个;
2、rating比身边人高的分配到更多的糖果。
问最少需要多少糖果。

题目解析:
假设所有人rating一致,那么需要n个糖果;
如果有一人rating更高,那么需要n+1;
如果有2人rating更高,则看两个人是否相邻,需要n+2或n+3个糖果;
以此,可以得出一种分配方案:
从最小的rating值开始分配,每次观看旁边的人是否有糖果:
如果身边人有糖果,则分配max(左边, 右边) + 1;
如果身边人没有糖果,则分配1;
时间复杂度为O(NLogN),排序耗时。

收获一枚TLE;
那么对算法进行优化。
根据分配糖果的条件2,我们知道在一个单调递增中:(单调递减可以逆着看,就是单调递增)
分配的结果是1、2、3、4、5这样的序列;
那么,一个数组可以分成多个单调递增的序列;
然后反着遍历,找到单调递减的序列;
剩下的部分可以全部填1。

复杂度解析:
时间复杂度是O(N)
空间复杂度是O(N)

总结

给自己定的小目标50题,因为第一页某些题目质量较低,加了一些比较容易的目前进度33/50。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容