第八周LeetCode算法题两道

第一道

题目名称: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]);
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值