Facebook面试题

LeetCode 125. Valid Palindrome

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: “A man, a plan, a canal: Panama”
输出: true

示例 2:

输入: “race a car”
输出: false

class Solution {
public:
    /*
    把一个字母转换为大写或小写 异或32
    */
    
    bool check(char c) //检查是不是字母和数字
    {
        return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
    }
    
    bool isPalindrome(string s) {
        for(int i = 0, j = s.size() - 1; i < j; i++, j--)
        {
            while(i < j && !check(s[i])) i ++;//不是字母和数字 下一位  check(s[i])
            while(i < j && !check(s[j])) j --;
            if(s[i] != s[j] && s[i] != (s[j]^32)) return false;
        }
        return true;
    }
};

LeetCode 88. Merge Sorted Array

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3

输出: [1,2,2,3,5,6]

class Solution {
public:
    //归并排序
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int k = m + n - 1;
        m--, n--;
        while(m >= 0 && n >= 0)
        {
            if(nums1[m] > nums2[n]) nums1[k--] = nums1[m--];
            else nums1[k--] = nums2[n--];
        }
        while(n >= 0) nums1[k--] = nums2[n--];
    }
};

LeetCode 278. First Bad Version

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

示例:

给定 n = 5,并且 version = 4 是第一个错误的版本。

调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true

所以,4 是第一个错误的版本。

// Forward declaration of isBadVersion API.
bool isBadVersion(int version);

class Solution {
public:
    int firstBadVersion(int n) {
        int l = 1, r = n;
        while(l < r)
        {
            int mid = l + 0ll + r >> 1;
            if(isBadVersion(mid)) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};

LeetCode 98. Validate Binary Search Tree

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:

    2
   / \
  1   3

输出: true

示例 2:

输入:

    5
   / \
  1   4
     / \
    3   6

输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。

/**
 * 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 {
public:
    bool isValidBST(TreeNode* root) {
        if(!root) return true;
        int minv, maxv;
        return dfs(root, minv, maxv);
    }
    
    bool dfs(TreeNode* root, int &minv, int &maxv) //这里要改变值 用&
    {
        minv = maxv = root->val;
        if(root->left)
        {
            int leftminv, leftmaxv;
            if(!dfs(root->left, leftminv, leftmaxv)) return false;//左子树不是合法二叉搜索树
            if(leftmaxv >= root->val) return false;
            minv = leftminv;
        }
        if(root->right)
        {
            int rightminv, rightmaxv;
            if(!dfs(root->right, rightminv, rightmaxv)) return false;
            if(rightminv <= root->val) return false;
            maxv = rightmaxv;
        }
        return true;
    }
};	

LeetCode 173. Binary Search Tree Iterator

实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。

调用 next() 将返回二叉搜索树中的下一个最小的数。

示例:

Facebook面试题_第1张图片

BSTIterator iterator = new BSTIterator(root);
iterator.next(); // 返回 3
iterator.next(); // 返回 7
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 9
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 15
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 20
iterator.hasNext(); // 返回 false

提示:

next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。
你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 中至少存在一个下一个最小的数。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class BSTIterator {
public:
    //用栈模拟非递归的中序遍历
    stack<TreeNode*> stk;
    BSTIterator(TreeNode* root) {
        while(root)
        {
            stk.push(root);
            root = root->left;
        }
    }
    
    /** @return the next smallest number */
    int next() {
        auto t = stk.top();
        stk.pop();
        for(auto p = t->right; p; p = p->left) stk.push(p);
        return t->val;
    }
    
    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !stk.empty();
    }
};

/**
 * Your BSTIterator object will be instantiated and called as such:
 * BSTIterator* obj = new BSTIterator(root);
 * int param_1 = obj->next();
 * bool param_2 = obj->hasNext();
 */	

LeetCode 238. Product of Array Except Self

给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

输入: [1,2,3,4]
输出: [24,12,8,6]

说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。

进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)

class Solution {
public:
    /*
    分成两半 前面一半相乘 * 后面一半相乘
    output[i]:0, 1, ..., i - 1, (i) , i + 1, i + 2, ... n - 1 
    */
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> res(nums.size());
        for(int i = 0, t = 1; i < nums.size(); i++)
        {
            res[i] = t; //t表示从0到i-1个数的乘积
            // cout << "i =" << i << "  " << res[i] << endl;
            t *= nums[i];
            // cout << t << endl;
        }
        for(int i = nums.size() - 1, t = 1; i >= 0; i--)
        {
            res[i] *= t;
            t *= nums[i];
            // cout << "i =" << i << "  " << res[i] << endl;
            // cout << t << endl;
        }
        return res;
    }
};

LeetCode 56. Merge Intervals

给出一个区间的集合,请合并所有重叠的区间。

示例 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

/*
1.按照区间左端点从小到大排序,从前往后遍历区间,遍历时维护当前区间
[st, ed]

interval[i] 遍历的区间
1.
interval[i].start(左端点) > ed:
    把[st, ed]添加到答案中去
    令[st, ed] = interval[i]

2.interval[i].start < = ed:
    ed = max(ed, interval[i].end)

*/
class Solution {
public:
    //比较函数
    static bool cmp(vector<int> &a, vector<int> &b)
    {
        return a[0] < b[0];
    }
    
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> res;
        if(intervals.empty()) return res;
        sort(intervals.begin(), intervals.end(), cmp);        
        
        int st = intervals[0][0], ed = intervals[0][1];
        for(int i = 1; i < intervals.size(); i ++)
        {
             
            if(ed < intervals[i][0]) //intervals[i][0]
            {
                res.push_back({st, ed});
                st = intervals[i][0], ed = intervals[i][1];
            }
            else ed = max(ed, intervals[i][1]);                
        }
        res.push_back({st, ed});
        return res;
        
    }
};

LeetCode 75. Sort Colors

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

进阶:

一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
你能想出一个仅使用常数空间的一趟扫描算法吗?

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int zero = 0 , second = nums.size() - 1;
        for(int i = 0; i <= second; i++)//i <= second
        {
            while(nums[i] == 2 && i < second) swap(nums[i], nums[second --]);
            if(nums[i] == 0) swap(nums[i], nums[zero ++]);
        }
    }
};

LeetCode 133. Clone Graph

给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆)。图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node])。

示例:

Facebook面试题_第2张图片

输入:
{“KaTeX parse error: Expected '}', got 'EOF' at end of input: …"neighbors":[{"id”:“2”,“neighbors”:[{“KaTeX parse error: Expected 'EOF', got '}' at position 9: ref":"1"}̲,{"id”:“3”,“neighbors”:[{“KaTeX parse error: Expected 'EOF', got '}' at position 9: ref":"2"}̲,{"id”:“4”,“neighbors”:[{“KaTeX parse error: Expected 'EOF', got '}' at position 9: ref":"3"}̲,{"ref”:“1”}],“val”:4}],“val”:3}],“val”:2},{"$ref":“4”}],“val”:1}

解释:
节点 1 的值是 1,它有两个邻居:节点 2 和 4 。
节点 2 的值是 2,它有两个邻居:节点 1 和 3 。
节点 3 的值是 3,它有两个邻居:节点 2 和 4 。
节点 4 的值是 4,它有两个邻居:节点 1 和 3 。

提示:

节点数介于 1 到 100 之间。
无向图是一个简单图,这意味着图中没有重复的边,也没有自环。
由于图是无向的,如果节点 p 是节点 q 的邻居,那么节点 q 也必须是节点 p 的邻居。
必须将给定节点的拷贝作为对克隆图的引用返回。

/*
1.先把每个点复制一遍,维护哈希表,可以从原点得到新点
2.遍历所有边(a,b)在新点之间,建立新的边(a',b')
/*
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector neighbors;

    Node() {}

    Node(int _val, vector _neighbors) {
        val = _val;
        neighbors = _neighbors;
    }
};
*/
class Solution {
public:
    unordered_map<Node*, Node*> hash;
    
    Node* cloneGraph(Node* node) {
        if(!node) return node;
        
        //创建新点
        auto p = new Node(node->val);
        hash[node] = p;//可以从node得到新的点
        
        dfs(node);
        return p;        
    }
    
    void dfs(Node* node) //遍历整个图
    {
        for(auto ver : node->neighbors)//遍历邻接节点
        {
            if(!hash.count(ver))//没有节点 先创建
            {
                hash[ver] = new Node(ver->val);
                dfs(ver); //新创建节点 遍历
            }
            //连接新点
            hash[node]->neighbors.push_back(hash[ver]);
        }
    }
};	

LeetCode 76. Minimum Window Substring

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

示例:

输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

说明:

如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

class Solution {
public:
    //双指针
    string minWindow(string s, string t) {
        string res;
        unordered_map<char, int> S, T;//S维护区间当中的字母个数
        //统计t里面每个字母出现次数
        for(auto c : t) T[c] ++;
        int total = T.size(); //t有多少个字母
        int satisfy = 0; //当前满足了多少个字母
        for(int i = 0, j = 0; i < s.size(); i++)
        {
            S[s[i]] ++;
            if(S[s[i]] == T[s[i]]) satisfy ++;
            while(S[s[j]] > T[s[j]]) S[s[j ++]] --;//先--后++ 有多余的字母
            if(satisfy == total && (res.empty() || i - j + 1 < res.size()))//当前答案小于答案最小长度就更新
                res = s.substr(j, i - j + 1);
        }
        return res;
    }
};

你可能感兴趣的:(LeetCode刷题,LeetCode)