Leetcode 08 09 11 12 13 14

08 字符串转换整数(atoi)

难度:中等
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0 。
提示:
本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:
输入: “42”
输出: 42

示例 2:
输入: " -42"
输出: -42
解释: 第一个非空白字符为 ‘-’, 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:
输入: “4193 with words”
输出: 4193
解释: 转换截止于数字 ‘3’ ,因为它的下一个字符不为数字。

示例 4:
输入: “words and 987”
输出: 0
解释: 第一个非空字符是 ‘w’, 但它不是数字或正、负号。
因此无法执行有效的转换。

示例 5:
输入: “-91283472332”
输出: -2147483648
解释: 数字 “-91283472332” 超过 32 位有符号整数范围。
因此返回 INT_MIN (−231) 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/string-to-integer-atoi

题解:一道非常恶心的题,不难,但是恶心。需要考虑到很多种情况。提交的时候有点急了,导致错误了很多次。应尽可能枚举出所有的情况。自己没有考虑到的情况包括,±2的情况,- 234的情况。因此解题时可以先找符号和空格,之后再去判断数字。同时,在数字相乘的时候,要考虑到算乘法的过程中也可能超过int的界限。

class Solution {
public:
    int myAtoi(string str) {
        int flag = 0;
        long long ans = 0;
        int i;
        for (i = 0; i < str.size(); i++) {
            if (str[i] == ' ' && flag ==0){
                continue;
            }
            if (str[i] == '+' && flag == 0) {
                flag = 1;
                continue;
            }
            if (str[i] == '-' && flag == 0) {
                flag = -1;
                continue;
            }
            break;
        }
        for (; i < str.size(); i++) {
            if (str[i] >= '0' && str[i] <= '9') {
                if (ans > INT_MAX)  break;
                if (ans < INT_MIN)  break;
                ans *= 10;
                ans += str[i] - '0';
            }
            else    break;
        }
        if (flag == -1)
            ans *= -1;
        if (ans > INT_MAX)
            return INT_MAX;
        if (ans < INT_MIN)
            return INT_MIN;
        return ans;
    }
};

09 回文数

难度:简单
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:
输入: 121
输出: true

示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。

进阶:
你能不将整数转为字符串来解决这个问题吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-number

题解:这道题是一道题,重点在要不通过字符串的方式来进行反转,那就通过取模的方式来转换成反转后的数字,判断两数字是否相等。注意的是,对于INT_MAX反转后会超过int的存储范围,所以可以使用long来存储数值。

class Solution {
public:
    bool isPalindrome(int x) {
        if (x < 0)  return false;
        long y = 0, tmp = x;;
        while (x) {
            y *= 10;
            y += x % 10;
            x /= 10;
        }
        return tmp == y ? true: false;
    }
};

11 盛最多水的容器

难度:中等
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。
在这里插入图片描述
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water

题解:开始想的是用O(n^2)的动态规划来解,瞄了一眼题解,原来还有线性的解法,于是开始冥思苦想。开始想着两个指针都从左端开始,后来发现无法更新,才想明白,一定是两个指针分别在左右端点向中间靠拢的。聚拢的方式为左右端点谁更小就谁先向中间聚拢,聚拢的同时维护最大值即可,没有坑点。

class Solution {
public:
    int maxArea(vector<int>& height) {
        int ans = 0;
        int l = 0, r = height.size() - 1;
        while (l < r) {
            if (height[l] < height[r]) {
                ans = max(ans, height[l] * (r - l));
                l++;
            }
            else {
                ans = max(ans, height[r] * (r - l));
                r--;
            }
        }
        return ans;
    }
};

12 整数转罗马数字

难度:中等
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

示例 1:
输入: 3
输出: “III”

示例 2:
输入: 4
输出: “IV”

示例 3:
输入: 9
输出: “IX”

示例 4:
输入: 58
输出: “LVIII”
解释: L = 50, V = 5, III = 3.

示例 5:
输入: 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman

题解:一道非常无脑,考验耐心的题目,可以把字符都提前存放到数组中。我直接无脑模拟了。

class Solution {
public:
    string intToRoman(int num) {
        string ans = "";
        if (num >= 1000) {
            for (int i = 0; i < num / 1000; i++) {
                ans += "M";
            }
            num %= 1000;
        }
        if (num >= 500) {
            if (num / 100 == 9) {
                ans += "CM";
                num %= 100;
            }
            else {
                ans += "D";
                num -= 500;
            }
        }
        if (num >= 100) {
            if (num / 100 == 4) {
                ans += "CD";
            }
            else {
                for (int i = 0; i < num / 100; i++) {
                    ans += "C";
                }
            }
            num %= 100;
        }
        if (num >= 50) {
            if (num / 10 == 9) {
                ans += "XC";
                num %= 10;
            }
            else {
                ans += "L";
                num -= 50;
            }
        }
        if (num >= 10) {
            if (num / 10 == 4) {
                ans += "XL";
            }
            else {
                for (int i = 0; i < num / 10; i++) {
                    ans += "X";
                }
            }
            num %= 10;
        }
        if (num >= 5) {
            if (num == 9) {
                ans += "IX";
                num -= 9;
            }
            else {
                ans += "V";
                num -= 5;
            }
        }
        if (num > 0) {
            if (num == 4) {
                ans += "IV";
            }
            else {
                for (int i = 0; i < num; i++) {
                    ans += "I";
                }
            }
            num = 0;
        }
        return ans;
    }
};

13 罗马数字转整数

难度:简单
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

示例 1:
输入: “III”
输出: 3

示例 2:
输入: “IV”
输出: 4

示例 3:
输入: “IX”
输出: 9

示例 4:
输入: “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.

示例 5:
输入: “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

提示:
题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
IC 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/roman-to-integer

题解:这道题和12题非常的类似,只是变成了从罗马数字转换成整数。这次使用了一个map,用来找对应的位置。左边的比右边数字小就减,否则就加。通过看大佬的写法发现了一个新的东西,map不用非得用map<char, int> 这样的声明。可以直接用一维int数组,把罗马数字对应成下标,这样可以加快运行速度。

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

14 最长公共前缀

难度:简单
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”

示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-prefix

题解:可以从第0个字符串按顺序取字母,都相同就加在答案字符串上,有不相同或字符串长度不够的,直接返回答案。注意的是,要判断字符串数组是否为空,不然访问strs[0]会运行错误。

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string ans = "";
        for (int i = 0; strs.size() && i < strs[0].size(); i++) {
            for (int j = 1; j < strs.size(); j++) {
                if (strs[j].size() < i || strs[j][i] != strs[0][i]){
                    return ans;
                }
            }
            ans += strs[0][i];
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值