LeetCode 11-14

来源:互联网 发布:section软件 编辑:程序博客网 时间:2024/05/16 04:32

Problem 11 Container With Most Water

这道题本质上是计算一个梯形中最大矩形面积。也就是,选定两个点之后(这两个点分别用 (i,ai)(j,aj) 来表示)矩形面积 = 宽度(abs(i - j)) x 高度(min(ai, aj)),并且取出其中最大的一个。首先想到的就是直接遍历所有可能性。然而,最后一组测试是15000个数据,对于一个 O(n2) 复杂度的算法来说,超时是必然的。
那有没有什么优化的方法呢?这里主要考虑有没有哪些过程是可以舍弃的。我们可以这样理解这个过程:每次选定一个点,将这个点的ai作为矩形的高,那也就意味着,我们只需要找得到离这个点的横向距离最远的那个点,并且 aj>ai 就可以了。有了思路代码实现就很简单了。

int maxArea(vector<int>& height) {    int size = height.size();    if (size <= 1)        return 0;    int ans = (height[0] > height[1] ? height[1] : height[0]);    for (int i = 0; i < size; i++) {        for (int j = 0; j < i; j++) {            if (height[j] >= height[i]) {                int area = (i - j) * height[i];                ans = (ans > area ? ans : area);                break;            }        }        for (int k = size - 1; k > i; k--) {            if (height[k] >= height[i]) {                int area = (k - i) * height[i];                ans = (ans > area ? ans : area);                break;            }        }    }    return ans;}

Problem 12 & 13 Integer ↔ Roman

阿拉伯数字和罗马数字的互相转换问题,关于罗马数字的介绍参考这里
题目中用得到的数据见下表:

Symbol I V X L C D M Value 1 5 10 50 100 500 1000

题中用到的一些特殊数字的表达方式见下表:

Number 4 9 40 90 400 900 Notation IV IX XL XC CD CM

首先我们来看阿拉伯数字转换成罗马数字。
简单来说,罗马数字是按照位来转换的。对于阿拉伯数字中的每一位 n,都可以分为以下4中情况讨论:
进行以上讨论时,会牵扯到字符的组合,一个简单的方法是用数组char Roman[7] = { 'I','V','X','L','C','D','M' },在数位和数组下标之间形成映射关系。对于第 k 位数,它对应的数组下标应该是 k×2k×2+1

n == 0 不作任何操作 n < 4 n 个 Roman[k * 2] n == 4 Roman[2 * k] + Roman[2 * k + 1] n < 9 Roman[2 * k + 1]和 n - 5 个Roman[2 * k + 2]) n == 9 Roman[2 * k] + Roman[2 * k + 2]

由于最后需要倒序输出,在具体实现过程中需要把字符的位置颠倒。

string intToRoman(int num) {    char Roman[7] = { 'I','V','X','L','C','D','M' };    string result_temp = "";    for (int k = 0; num > 0; k++) {        int digit = num % 10;        if (digit != 0) {            if (digit < 4) {                for (int i = 0; i < digit; i++)                    result_temp.push_back(Roman[2 * k]);            }            else if (digit == 4)            {                result_temp.push_back(Roman[2 * k + 1]);                result_temp.push_back(Roman[2 * k]);            }            else if (digit < 9) {                digit = digit - 5;                for (int i = 0; i < digit; i++)                    result_temp.push_back(Roman[2 * k]);                result_temp.push_back(Roman[2 * k + 1]);            }            else if (digit == 9) {                result_temp.push_back(Roman[2 * k + 2]);                result_temp.push_back(Roman[2 * k]);            }        }        num = num / 10;    }    int size = result_temp.length();    string result = "";    for (int j = size - 1; j >= 0; j--)        result += result_temp[j];    return result;}

接下来考虑罗马数字转换成阿拉伯数字。
首先我们知道罗马数字的最高位在最左边,但是有一个问题,就是当出现4或9这样的数字的时候是有两个罗马数字组合而成的,好在这样的数字都有一个特地啊,那就是开头一定是 I X C,那么只要在每次遇到这些数字的时候判断一下后面的字符是否会构成这些特殊字符即可。同时需要注意的是首先应该判断是否存在下一个字符,否则会出现越界的情况。

int romanToInt(string s) {    map<char, int> Roman;    Roman['I'] = 1;    Roman['V'] = 5;    Roman['X'] = 10;    Roman['L'] = 50;    Roman['C'] = 100;    Roman['D'] = 500;    Roman['M'] = 1000;    int size = s.length();    int result = 0;    for (int i = 0; i < size; i++) {        map<char, int>::iterator to_find = Roman.find(s[i]);        if (i + 1 < size && to_find->second < 500) {            map<char, int>::iterator match = Roman.find(s[i + 1]);            // Check 9            if (match->second == to_find->second * 10) {                result += to_find->second * 9;                i++;            }            // Check 4            else if (match->second == to_find->second * 5) {                result += to_find->second * 4;                i++;            }            else {                result += to_find->second;            }        }        else {            result += to_find->second;        }    }    return result;}

Problem 14 Longest Common Prefix

求最长公共前缀,这里采用分治的思想。将数组分为两部分,对每个部分求最长公共前缀,最后将每个部分求得的最长公共前缀合并起来。

string sub_common_prefix(vector<string>& sub_) {    int size = sub_.size();    if (size == 0)        return "";    if (size == 1)        return sub_[0];    int mid = size / 2;    vector<string> left(sub_.begin(), sub_.begin() + mid);    vector<string> right(sub_.begin() + mid, sub_.end());    string left_ = sub_common_prefix(left);    string right_ = sub_common_prefix(right);    int size_left = left_.length(), size_right = right_.length();    if (size_left == 0 || size_right == 0)        return "";    if (size_left < size_right) {        int i;        for (i = 0; i <= size_left && left_.substr(0, i) == right_.substr(0, i); i++);        return left_.substr(0, i - 1);    }    else {        int i;        for (i = 0; i <= size_right && left_.substr(0, i) == right_.substr(0, i); i++);        return right_.substr(0, i - 1);    }}string longestCommonPrefix(vector<string>& strs) {    return sub_common_prefix(strs);}
0 0
原创粉丝点击