【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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值