第一道
题目名称:17. Letter Combinations of a Phone Number
题目难度:Medium
题目描述:Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
题目分析:
本题乍一看好像可以用穷举的多重循环算法直接暴力解决,但是仔细一想,这种方式实现起来的话有一些细节方面的困难。每一个数字都需要一重新的循环,虽然说每个数字对应的字符串的长度最多为4,多重循环的算法效率不会太低。But,我们事先并不知道输入的数字串的长度是多少,因此根本不可能写一个适合所有情况的循环。
于是我们把眼光放到了递归算法。递归适合处理这种无法预先知道何时停止的情况。
算法的基本思路是:
先用一个队列维持输入数字串对应的多个字符串。
然后进行多重递归调用。
每一次递归调用处理掉队列中的一个字符串,对这个字符串做这样的处理:循环处理字符串中的每一个字符。
这个循环要做的是:生成当前目标字符串的一个新副本,将当前对应处理的字符添加到副本的末端,然后立刻进行下一轮的递归调用。这样,每一轮递归调用中,生成了最多4种新的子情况,这4种子情况又分别向下递归,互不影响、互不干扰。
递归结束的条件是维持输入数字串对应的多个字符串的队列为空,说明我们已经处理了所有的字符串,此时将当前字符串加入结果的向量vector中即可。
最后AC的代码是:
class Solution {
public:
string getLetters(char c) {
switch(c) {
case '2': return "abc";
case '3': return "def";
case '4': return "ghi";
case '5': return "jkl";
case '6': return "mno";
case '7': return "pqrs";
case '8': return "tuv";
case '9': return "wxyz";
default : return "";
}
}
void findAll(vector<string> & result, string r, queue<string> q) {
if (q.empty()) {
result.push_back(r);
return;
} else {
string curStr = q.front();
q.pop();
for (int i = 0; i < curStr.size(); ++i) {
string temp = r + curStr[i];
findAll(result, temp, q);
}
}
}
vector<string> letterCombinations(string digits) {
vector<string> result;
if (digits == "") return result;
queue<string> q;
for (int i = 0; i < digits.size(); ++i) {
string letters = getLetters(digits[i]);
q.push(letters);
}
findAll(result, "", q);
return result;
}
};
第二道
题目名称:48. Rotate Image
题目难度:Medium
题目描述:You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Note:
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example 1:
Given input matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
rotate the input matrix in-place such that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
Example 2:
Given input matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
rotate the input matrix in-place such that it becomes:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
题目分析:
原地旋转矩阵的题目很经典。一个通用的解法是:
- 对于顺时针方向旋转的,我们先将矩阵垂直翻转,再沿着对角线翻转即可。如图:
1 2 3 7 8 9 7 4 1
4 5 6 => 4 5 6 => 8 5 2
7 8 9 1 2 3 9 6 3
- 对于逆时针方向的旋转,先将矩阵水平翻转,再将矩阵沿着对角线翻转:
1 2 3 3 2 1 3 6 9
4 5 6 => 6 5 4 => 2 5 8
7 8 9 9 8 7 1 4 7
最后AC的代码如下:
class Solution {
public:
void rotate(vector<vector<int> > &matrix) {
reverse(matrix.begin(), matrix.end());
for (int i = 0; i < matrix.size(); ++i) {
for (int j = i + 1; j < matrix[i].size(); ++j)
swap(matrix[i][j], matrix[j][i]);
}
}
};