【LeetCode】Algorithms 題集(四)

Maximum Subarray

題意:

    Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

    For example, given the array [−2,1,−3,4,−1,2,1,−5,4],

    the contiguous subarray [4,−1,2,1] has the largest sum = 6.

思路:

     很直接的最長上升子序列,線性 dp, dp 式子爲:

     dp[i] = dp[i-1] > 0?(A[i] + dp[i-1]):A[i]

     然後迭代更新最大值就好。

代碼:

class Solution {
public:
    int maxSubArray(int A[], int n) {
        int ans = A[0];
        int *dp = new int[n];
        dp[0] = A[0];

        for(int i = 1;i < n;++i)
        {
            dp[i] = dp[i-1]>0?(A[i] + dp[i-1]):A[i];
            if(dp[i] > ans)
                ans = dp[i];
        }

        return ans;
    }
};

Single Number II

題意:

    Given an array of integers, every element appears three times except for one. Find that single one.
    Note:
    Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

思路:

     用 ones, twos, threes 分別記錄數字在二進制表示中對應位置 1 出現的次數。變量更新如下:首先更新 twos, 對應位置出現兩次的爲上一次對應位置出現兩次的加上一次出現一次的和新的數的與,ones 爲對應位置出現一次的爲上一次出現一次的異或上新的數,threes 爲對應位置出現了一次的再與上出現了兩次的位置。

     然後再把 ones 和 twos 中 含有 threes 中 1 的位置的那些去掉。

     這道題的位運算很微妙,值得好好體會。你可以想想 ones、twos 和 threes 是怎麼來的?計算的先後順序能不能變化?threes 爲什麼可以用 ones 和 twos 的值來算?

代碼:

class Solution {
public:
    int singleNumber(int A[], int n) {
        int ones = 0, twos = 0, threes = 0;

        for(int i = 0;i < n;++i)
        {
            twos = twos | ones & A[i];
            ones = ones ^ A[i];
            threes = ones & twos;

            ones = ones & ~threes;
            twos = twos & ~threes;
        }

        return ones;
    }
};


Majority Element

題意:

     Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

     You may assume that the array is non-empty and the majority element always exist in the array.

思路:

     在數組中找出出現次數大於 n/2 的數。

     C++ 中map 對於這種統計次數的問題來說特別方便,如果用 Python 的話當然用字典。

代碼:

class Solution{
public:
    int majorityElement(vector<int> &num) {
        vector<int>::iterator it = num.begin();
        int n = num.size();
        map<int,int> count;
        for(;it != num.end();it++)
        {
            // 這裏爲什麼不用判斷鍵是否存在?因爲不存在時初始化爲 0
            if(++count[*it] > n/2)
            {
                return *it;
            }
        }
    }
};

Climbing Stairs

題意 :

     You are climbing a stair case. It takes n steps to reach to the top.
     Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

思路:

     簡單遞推, 爬階梯問題。第 i 層階梯等於你從第 i -1 層邁一步上來或者從第 i-2 層邁兩步上來。

代碼:

class Solution {
public:
    int climbStairs(int n) {
        int *dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2;i <= n;++i)
            dp[i] = dp[i-1] + dp[i-2];
        return dp[n];
    }
};


Convert Sorted Array to Binary Search Tree

題意:

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

思路:

    根據有序列表構造平衡的二叉查找樹。關鍵在於二叉樹保持平衡,但因爲數組爲有序的,所以直接取數組中間元素作爲二叉樹的根,再用左右區間構造左右子樹,遞歸進行就好。

代碼:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *sortedArrayToBST(vector<int> &num) {
        if(num.size() == 0) return NULL;
        return build(num,0,num.size());
    }

    TreeNode *build(vector<int>&num,int st, int ed)
    {
        if(st == ed) return NULL;

        int m = (st + ed)/2;

        TreeNode* root = new TreeNode(num[m]);

        root->left = build(num,st,m);
        root->right = build(num,m+1,ed);

        return root;
    }
};
發佈了123 篇原創文章 · 獲贊 268 · 訪問量 111萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章