LeetCode 力扣 刷题记录(11 - 15)题目+算法分析+Cpp解答

11.Container With Most Water

双指针法:

高度低的指针必须向着高度高的指针的方向靠拢:通过高度弥补宽度的减小。

class Solution {
public:
    int maxArea(vector<int>& height) {
        vector<int>::iterator left,right;
        int ans = 0;
        int len = height.size() - 1;
        left = height.begin();
        right = height.end();
        right--;
        while(left != right){
            if(*left > *right){
                if(ans < len * *(right)){
                    ans = len * *(right);
                }
                right--;
            }
            else{
                if(ans < len * *(left)){
                    ans = len * *(left);
                }
                left++;
            }
            len--;
        }
        return ans;
    }
};

12.Integer to Roman

人工哈希 + 贪心算法:

class Solution {
public:
    string intToRoman(int num) {
        string ans = "";
        map<int,string> hash;
        hash[1000] = "M";
        hash[900] = "CM";
        hash[500] = "D";
        hash[400] = "CD";
        hash[100] = "C";
        hash[90] = "XC";
        hash[50] = "L";
        hash[40] = "XL";
        hash[10] = "X";
        hash[9] = "IX";
        hash[5] = "V";
        hash[4] = "IV";
        hash[1] = "I";
        map<int,string>::reverse_iterator mit;
        for(mit=hash.rbegin();mit!=hash.rend();){
            if(num >= mit->first){
                ans += mit->second;
                num -= mit->first;
            }
            else
                mit++;
        }
        return ans;
    }
};

纯人工哈希:

class Solution {
public:
    string intToRoman(int num) {
        string c[4][10] = {
            {"","I","II","III","IV","V","VI","VII","VIII","IX"},
            {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
            {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
            {"","M","MM","MMM"}
        };
        string ans;
        ans += c[3][num / 1000];
        ans += c[2][num / 100 % 10];
        ans += c[1][num / 10 % 10];
        ans += c[0][num % 10];
        return ans;
    }
};

13.Roman to Integer

人工哈希表 + 前一字符判断:

​ 正常顺序:前一个字符的数值是大于等于后一个字符的数值的。

​ 如果前一个字符的数值小于后一个字符的数值,需要减去两个前一字符的数值,得到正确值。

class Solution {
public:
    int romanToInt(string s) {
        map<char,int> hash = {{'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}};
        int len = s.length();
        int ans = 0;
        for(int i=0;i<len;i++){
            ans += hash[(char)s[i]];
            if(i > 0 && hash[(char)s[i]] > hash[(char)s[i-1]]){
                ans -= hash[(char)s[i-1]] * 2;
            }
        }
        return ans;
    }
};

14.Longest Common Prefix

纵向比较:

​ 首先比较全部字符串的第一个字符,然后再比较全部字符串的第二个字符,以此类推,直到出现字符不相同或者字符串结束,得到答案。

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string ans = "";
        if(strs.empty())
            return ans;
        int size = strs.size();
        int len = strs[0].length();
        for(int i=0;i<len;i++){
            for(int j=1;j<size;j++){
                if(i >= strs[j].length() || strs[0][i] != strs[j][i])
                    return ans;
            }
            ans += strs[0][i];
        }
        return ans;
    }
};

15.3Sum

排序 + 双指针遍历:

​ 首先,将给定的数组进行排序(从小到大的顺序)。

​ 遍历排序后的数组中的每一个数,如果这个数之前已经讨论过了则可以跳过。

​ 将取出的数作为“目标”,使用双指针在排序后的数组中找另外的两个数:

​ 一个左指针指向该取出的数的后一个数,即此时的最低位。

​ 另一个右指针指向数组的最后一个数,即此时的最高位。

​ 由于数组已经是从小到大进行排序了,所有令此时的三个数的和为 sum:

  • 如果 sum > 0,说明右指针指向的数太大,要向左移,即使得所指的数变小(如果向左移后的数和之前一样大则需要继续向左移);
  • 如果 sum < 0,说明左指针指向的数太小,要向右移,即使得所指的数变大(如果向右移后的数和之前一样大则需要继续向右移);
  • 如果 sum = 0,说明找到答案,并让左指针和右指针都向中间靠拢,看有没有新的答案。
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int len = nums.size();
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end());
        for(int i=0;i<len-2;i++){
            if(i > 0 && nums[i-1] == nums[i])
                continue;
            int left = i+1,right = len-1;
            while(left < right){
                int sum = nums[i] + nums[left] + nums[right];
                if(sum > 0)
                    while(left < --right && nums[right] == nums[right+1]);
                else if(sum < 0)
                    while(++left < right && nums[left-1] == nums[left]);
                else{
                    vector<int> temp = {nums[i],nums[left],nums[right]};
                    ans.push_back(temp);
                    while(++left < right && nums[left] == nums[left-1]);
                    while(left < --right && nums[right] == nums[right+1]);
                }
            }
        }
        return ans;
    }
};
发布了36 篇原创文章 · 获赞 5 · 访问量 5230

猜你喜欢

转载自blog.csdn.net/qq_43413123/article/details/104983415
今日推荐