您的位置:首页 > 其它

算法设计与应用基础 - Week01

2016-09-03 15:34 309 查看

算法设计与应用基础 - Week01

博客动机

其实一直挺想开个技术博客,一方面可以整理自己的知识库,一方面也可以通过交流、填坑来激励自己的成长。不过就像林老师说的那样,觉得发表到博客上的东西必须经得起考验,而自己恰恰没有那么扎实的基础,所以迟迟没有行动。

这次因为课程的原因,不得不把自己浅薄的见解发表于此,希望能够以此为契机,养成写博客的习惯:);也希望自己能够成为一个负责任的博主,博文里大概会有许多错误,希望各位朋友、同学能够指出,我会坚持修补的 √

第一周目标

自数据结构课程结束以来几乎就没有用过C++了,要么是操作系统实验里连库都要自己写的C语言,要么是实验室里的Python,总的来说,C++已经完全荒废了…orz

所以前几周主要是让自己重新熟悉C++,不去挑选特定类别的题目,而是使用LeetCode的Pick One功能来随机选择。

LeetCode 385. Mini Parser

抽到的第一题题意很直观,也就是解析字符串并用题目给定的类表示出来;字符串有两种类型,一种表示单整数,另一种表示嵌套列表类型。

观察给定类的接口

因为题目要求最终结果用给定的类表示,首先要理清给定类的接口。简单梳理一下类的接口,可以表示成下面的结构图(这种表示方法或许不太规范,如果同学们有简明规范的表示方法,希望能给我安利一下~)。

class NestedInteger
|--- Constructor
|    |--- NestedInteger()
|    |--- NestedInteger(int value)
|
|--- Single Integer
|    |--- isInteger(): bool const
|    |--- getInteger(): int const
|    |--- setInteger(int value): void
|
|--- Nested Integer
|    |--- add(const NestedInteger &ni): void
|    |--- getList(): const vector<NestedInteger> & const


因为这题只涉及列表的构造,基本上只需要用到两个构造函数以及成员函数add,其他暂时就不需要理会了。

解析单整数

单整数的解析非常简单,题目给出

String contains only digits
0-9
,
[
,
-
,
,
,
]
.

因此负数也包括在内,解析单整数的时候需要先判断符号,然后依次解析数字。用一个成员函数表示如下:

int parseNum(string s) {
if (s.empty()) return 0;

bool is_neg = false;
int i, num = 0;

if (s[0] == '-') is_neg = true, i = 1;
else i = 0;

for (; i < s.size(); i++) {
num *= 10;
num += (s[i] - '0');
}

return is_neg == true ? -num : num;
}


使用递归解析嵌套列表

解决嵌套问题一个最直观的方法便是递归,递归基可以是单个整数,也可以是空。前面已经写出了单整数的解析函数,这部分只要把递归步表示出来就可以了。

问题在于如何表示递归步。可以观察到,一个嵌套列表总是由成对
[]
包围,处理一个嵌套列表的字符串时,只需要考虑字符串下标为 [1, size - 1) 的部分就可以了。

如果元素是单整数,那么子串的首位一定不是
[
,遇到字符
,
或字符串遍历完成则表示到达子串的尾部,得到子串在字符串中的首位和尾部即可以将其作为递归步的输入。

beg = i;
/* other codes */
// A single integer
else if (s[i] != '[') {
i++;
for (; i < s.size() - 1; i++) {
if (s[i] == ',') break;
}
out.add( deserialize( s.substr(beg, i - beg) ) );
}


如果元素是嵌套列表,那么要统计
[
]
出现的次数。使用变量
cnt
进行计数,遇到字符
[
时变量
cnt
加1,遇到字符
]
时变量
cnt
减1,一旦变量
cnt
的值为0,则表示获得了一个嵌套列表子串。

// A nested list
else {
cnt = 1; i++;
for (; i < s.size() - 1; i++) {
if (s[i] == '[') cnt++;
else if (s[i] == ']') {
cnt--;
if (cnt == 0) {
i++;
break;
}
}
}
out.add( deserialize( s.substr(beg, i - beg)) );
}


完整代码如下:

class Solution {
public:
NestedInteger deserialize(string s) {
if (s.empty()) return NestedInteger();
if (s[0] != '[') return NestedInteger( parseNum(s) );

NestedInteger out;
int beg, cnt;

for (int i = 1; i < s.size() - 1; i++) {
beg = i;

if (s[i] == ',');
else if (s[i] == ']');

// A single integer
else if (s[i] != '[') {
i++;
for (; i < s.size() - 1; i++) {
if (s[i] == ',') break;
}
out.add( deserialize(s.substr(beg, i - beg)) );
}

// A nested list else { cnt = 1; i++; for (; i < s.size() - 1; i++) { if (s[i] == '[') cnt++; else if (s[i] == ']') { cnt--; if (cnt == 0) { i++; break; } } } out.add( deserialize( s.substr(beg, i - beg)) ); }
}

return out;
}

int parseNum(string s) { if (s.empty()) return 0; bool is_neg = false; int i, num = 0; if (s[0] == '-') is_neg = true, i = 1; else i = 0; for (; i < s.size(); i++) { num *= 10; num += (s[i] - '0'); } return is_neg == true ? -num : num; }
};


第一次写太过啰嗦了…有空的时候精简一下…orz
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 算法