程序员

Leetcode刷题总结(4):Mock Interview

2018-04-09  本文已影响242人  张慕晖

emm……结果每个session就一道题?

似乎简单题是30分钟,中等题是40分钟,难题是60分钟,而且还会出来一些写bash的题目之类的。感觉没什么特别的意思,还是去做top interview问题好了。

99

题意

给你一个二叉搜索树,里面两个元素被交换了。请将二叉搜索树复原。

分析

用O(n)的空间复杂度的话,非常直接。对树进行中序遍历,把结果存下来,然后把这个结果排序,和原来比较一下,就知道是哪两个数交换了。于是一遍过。(不需要交换结点,只需要交换值,这一点倒是很简单。)

emm,如果需要常数空间复杂度,那就需要一些其他的比较复杂的遍历方式了(比如Morris Traversal中序遍历),而不是单纯的中序遍历(O(logn)的栈空间)。具体参见https://siddontang.gitbooks.io/leetcode-solution/content/tree/recover_binary_search_tree.html,因为时间紧迫,所以就不写了。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
/*
O(n)空间:把BST的全部元素都提取出来,然后排序;对BST做一个中序遍历,比较哪两个元素有差异。最后换回来。
常数空间的话,其实在中序遍历的过程中就可以判断哪两个元素是逆序的,记录下来
*/
class Solution {
private:
    vector<pair<int, TreeNode*>> curTree;
    
    void midTrav(TreeNode* root) {
        if (root == NULL)
            return;
        midTrav(root->left);
        curTree.push_back(make_pair(root->val, root));
        midTrav(root->right);
    }
    
public:
    void recoverTree(TreeNode* root) {
        midTrav(root);
        vector<pair<int, TreeNode*>> sortedTree(curTree);
        sort(sortedTree.begin(), sortedTree.end());
        
        TreeNode *x = NULL, *y = NULL;
        
        for (int i = 0; i < sortedTree.size(); i++) {
            if (curTree[i].first != sortedTree[i].first || curTree[i].second != sortedTree[i].second) {
                if (x == NULL)
                    x = curTree[i].second;
                else
                    y = curTree[i].second;
            }
        }
        
        swap(x->val, y->val);
    }
};

时间是80.86%。

115

题意

有两个字符串,S和T。计算S中与T相等的子序列的数量。

分析

那么可以用动态规划的想法:对于f[i],它表示,以S[i]结尾的S的某个子串能够与T的前几个字母匹配。但是这样不好做。不如定义f[i][j],表示以S[i]结尾的S的子串中,能够与T[0..j]完全匹配的数量。所以我们得到了一个递推方程:f[i][j] = sum(f[k][j - 1] (S[i] == T[j])), k = 0..i-1;,解的时间复杂度大约为O(mn^2)。显然,应用一些简单的部分和知识,这一时间可以缩减到O(mn)。

代码

class Solution {
public:
    int numDistinct(string s, string t) {
        
        if (s.length() < t.length())
            return 0;
        
        int n = s.length(), m = t.length();
        // f[i][j],表示以S[i]结尾的S的子串中,能够与T[0..j]完全匹配的数量
        int f[n+1][m+1];
        memset(f, 0, sizeof(f));
        
        for (int i = 0; i < n; i++) {
            if (s.substr(i, 1) == t.substr(0, 1))
                f[i][0] = 1;
        }
        
        for (int j = 1; j < m; j++) {
            for (int i = 0; i < n; i++) {
                // f[i][j] = sum(f[k][j - 1] (S[i] == T[j])), k = 0..i-1
                f[i][j] = 0;
                if (s.substr(i, 1) == t.substr(j, 1)) {
                    for (int k = 0; k < i; k++)
                        f[i][j] += f[k][j-1];
                }
            }
        }
        
        int ans = 0;
        for (int i = 0; i < n; i++)
            ans += f[i][m-1];
        return ans;
    }
};

时间为1.38%,毕竟复杂度比较大了。

653

题意

一个二叉搜索树,给定数k,找出其中是否有两个元素的和=k。

分析

此题过于简单了,不过我做得不够聪明。只要把树用中序遍历序列化,然后在两侧用两个指针找就可以了。当然用哈希表也可以。数据似乎过于的弱了,我瞎搞也搞出来了。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    vector<int> tree;
    void midTrav(TreeNode* root) {
        if (root == NULL)
            return;
        midTrav(root->left);
        tree.push_back(root->val);
        midTrav(root->right);
    }
    
    bool findVal(TreeNode* root, int val) {
        if (root == NULL)
            return false;
        if (val < root->val)
            return findVal(root->left, val);
        else if (val == root->val)
            return true;
        else
            return findVal(root->right, val);
    }
    
public:
    bool findTarget(TreeNode* root, int k) {
        midTrav(root);
        for (int i = 0; i < tree.size(); i++) {
            if (findVal(root, k - tree[i]) && tree[i] + tree[i] != k)
                return true;
        }
        return false;
    }
};

时间是42.98%。

上一篇下一篇

猜你喜欢

热点阅读