【LeetCode】Algorithms 题集(七)

来源:互联网 发布:花生壳ping域名失败 编辑:程序博客网 时间:2024/06/10 17:04

Contains Duplicate

题意:

     Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

思路:

    找出是否有重复元素。用 set 即可。

代码:

class Solution {public:    bool containsDuplicate(vector<int>& nums) {        set<int> distinct;        vector<int>::const_iterator it = nums.begin();        while(it != nums.end()){            if(distinct.count(*it)) return true;            distinct.insert(*it);            it++;        }        return false;    }};

Generate Parentheses

题意:

      Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

      For example, given n = 3, a solution set is:

     "((()))", "(()())", "(())()", "()(())", "()()()"

思路:

       结果的数量是卡诺兰数。找出所有结果可以用递归,剪枝或者说合法结果的判断关键在于递归过程中要保证剩余右括号的数量必须大于等于左括号。

代码:

class Solution {public:    vector<string> generateParenthesis(int n) {        vector<string> ans;        if(n == 0) return ans;        solve(n, n, "", ans);        return ans;    }        void solve(int l, int r, string cur, vector<string>& ans) {        if(r < l) return;                if(l == 0 && r == 0) {            ans.push_back(cur);            return;        }                if(l > 0) solve(l-1, r, cur+"(", ans);        if(r > 0) solve(l, r-1, cur+")", ans);        return;    }};

Binary Tree Inorder Traversal

题意:

Given a binary tree, return the inorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1    \     2    /   3

return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?

confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.

思路:

     中序遍历非递归。

代码:

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> inorderTraversal(TreeNode *root) {        vector<int> ans;        stack<TreeNode *> s;        TreeNode *p = root;        while(p != NULL || !s.empty())        {            while(p != NULL)            {                s.push(p);                p = p->left;            }            if(!s.empty())            {                p = s.top();                s.pop();                ans.push_back(p->val);                p = p->right;            }        }        return ans;    }};


Find Minimum in Rotated Sorted Array

题意:

     Suppose a sorted array is rotated at some pivot unknown to you beforehand.

     (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

     Find the minimum element.

     You may assume no duplicate exists in the array.

思路:

      在一个以某个元素为中心点旋转之后的有序数组,找数组中最小的数。

      伪装的二分。旋转之后,数组便是先从左到右升序,然后跌落,再从左到右升序,而且右边的最高值比左边的最低值要小。

      找最小的数,我们以数组最后一个数 end 为哨兵,不断拿当前区间中间的数 mid 和 end 比较。如果 mid <= end ,说明 mid 在第二段升序区间(或者数组只有一个数),那么最小的数肯定在左边,如果 mid > end,说明 mid 在第一段升序区间,那么最小的数肯定在右边。 

代码:

class Solution {public:    int findMin(vector<int> &num) {        int l = 0, r = num.size() - 1;        int end = num[r];        while(l<=r)        {            int mid = (l+r)/2;            if(num[mid] > end)            {                l = mid + 1;            }            else            {                r = mid - 1;            }        }        return num[l];    }};


Minimum Path Sum

题意:

     Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

     Note: You can only move either down or right at any point in time.

思路:

     一个矩阵每个方格都有非负权值,求从左上到右下的路径最小权值。明显 dp。但用个一维数组就好了,这里用 vector。基本的思想当然是从上往下迭代,从左往右迭代。

    为什么用一维呢?因为迭代到某个位置的时候,你只需要这个位置的左边和上边的最小权值,取出最小的那个加上矩阵这个位置的权值就好。而这个位置的迭代结果被写入之前,这个位置保存的就是上一次迭代的结果值。所以在一次从左到右的迭代过程中,一维数组里面一开始保存的全部是上次迭代的值,然后逐渐变成本次迭代的结果,最后全部被更新。

    注意矩阵第一行只能从左边到达,矩阵第一列只能从上边到达。看代码可能更清晰点。

代码:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        if(grid.size() == 0) return 0;                int m = grid.size();        int n = grid[0].size();        // 初始化为矩阵第一行        vector<int> dp(grid[0]);                // 第一行的数都必须从左边到达        for(int i = 1;i < n;++i)            dp[i] = dp[i-1] + grid[0][i];                for(int i = 1;i < m;++i) {            // 第一列的数都必须从上面到达            if(i != 0) dp[0] = grid[i][0] + dp[0];            for (int j = 1;j < n;++j) {                // 其他的数用原始矩阵的数加上左边或者上边最小的数                dp[j] = grid[i][j] + (dp[j-1] < dp[j]? dp[j-1]: dp[j]);            }        }        return dp[n-1];    }};


0 0
原创粉丝点击