第一道
题目名称:46. Permutations
题目难度:Medium
题目描述:Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
题目分析:
题目的意思就是给你一个没有重复数字的序列,要你找出这个序列中的数字的所有可能的组合情况。
可以非常自然地想到使用递归来解决这个问题。假设序列中数字的个数是n。我们初始的新序列为空。每一层递归遍历所有可以添加进这个新序列的情况。
比如例子中的1 2 3,第一层递归时,将新序列第一位可能的所有情况都遍历到。这样第一层递归之后新序列就有三种情况:[1]、[2]、[3],然后再在给定序列中,删除已经被使用的数字。例子中给定序列是[1,2,3],那么进入第二层的给定序列分别是:[2,3]、[1,3]、[1,2]。
这样,每一层遍历使用给定序列中的一个数,递归结束的条件是给定序列中的数字已经全部被使用。也就是说,给定序列的大小为0。
最后AC的代码如下:
class Solution {
public:
void nextOne(vector<vector<int> > & result, vector<int> current, vector<int> nums) {
if (nums.size() == 0) {
result.push_back(current);
return;
}
for (vector<int>::iterator it = nums.begin(); it!=nums.end(); it++) {
//新建一个当前未用数字序列的副本以用于之后的恢复
vector<int> temp(nums);
//这里重新new一个副本newCur是因为循环的每次都需要对current的序列作操作,但是这些操作又不能相互影响
vector<int> newCur(current);
//将一种新的情况添加到当前序列
newCur.push_back(*it);
//删除未用序列中刚刚已经被我么使用的数字
nums.erase(it);
nextOne(result, newCur, nums);
//因为删除操作在每次循环中不能相互影响,所以这里要做一个“恢复”的操作
nums = temp;
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > result;
vector<int> current;
nextOne(result, current, nums);
return result;
}
};
需要特别小心的是,递归时,什么参数可以使用其“引用“,什么参数需要重新建立一个副本。解题过程中题主也在这里掉过一个坑,相关的内容已写在代码注释中。
第二道
题目名称:14. Longest Common Prefix
题目难度:easy
题目描述:Write a function to find the longest common prefix string amongst an array of strings.
题目分析:
这道题要求我们找出所给的一系列字符串中公共的最长的前缀。思路特别简单:
先遍历一遍数组,找出长度最短的字符串。这个字符串最有可能成为“最长的公共前缀“。然后就从头到尾遍历这个候选者包含的字符,对于每一个字符,检查所给的字符串集合中每一个字符串对应的位置的字符是否相同。如果所有字符串对应位置的字符串都与之相同,那末将这个字符加入“结果字符串“result中,然后进入下一位字符的比较。如果不同,则已经找到了最长的公共前缀。
最后AC的代码如下:
class Solution {
public:
bool common(char c, int index, vector<string>& strs) {
for (int i = 0; i < strs.size(); i++) {
if (strs[i][index] != c)
return false;
}
return true;
}
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0)
return "";
int size = 100000;
string candidate, result = "";
for (int i = 0; i < strs.size(); ++i) {
if (strs[i].size() < size) {
size = strs[i].size();
candidate = strs[i];
}
}
for (int i = 0; i < size; i++) {
if (common(candidate[i], i, strs)) {
result += candidate[i];
} else {
return result;
}
}
return result;
}
};
需要注意的是测试样例中有空输入的情况,这种情况需要特殊处理。
本文解析了LeetCode上的两道经典算法题——求排列组合及寻找最长公共前缀,详细介绍了递归求解全排列的方法及如何通过遍历找到一系列字符串中的最长公共前缀。

被折叠的 条评论
为什么被折叠?



