【LeetCode算法系列题解】第66~70题

LeetCode 66. 加一(简单)

【题目描述】

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位,数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。

【示例1】

输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。

【示例2】

输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。

【示例3】

输入:digits = [0]
输出:[1]

【提示】

1 ≤ d i g i t s . l e n g t h ≤ 100 1\le digits.length\le 100 1digits.length100
0 ≤ d i g i t s [ i ] ≤ 9 0\le digits[i]\le 9 0digits[i]9

【分析】


简单的高精度模板题。


【代码】

class Solution {
    
    
public:
    vector<int> plusOne(vector<int>& digits) {
    
    
        int t = 1;
        for (int i = digits.size() - 1; t && i >= 0; i--)
        {
    
    
            t += digits[i];
            digits[i] = t % 10;
            t /= 10;
        }
        if (t) digits.insert(digits.begin(), 1);
        return digits;
    }
};

LeetCode 67. 二进制求和(简单)

【题目描述】

给你两个二进制字符串 ab,以二进制字符串的形式返回它们的和。

【示例1】

输入:a = "11", b = "1"
输出:"100"

【示例2】

输入:a = "1010", b = "1011"
输出:"10101"

【提示】

1 ≤ a . l e n g t h , b . l e n g t h ≤ 1 0 4 1\le a.length, b.length\le 10^4 1a.length,b.length104
ab 仅由字符 '0''1' 组成
字符串如果不是 "0",就不含前导零

【分析】


同样是高精度模板题,注意是二进制即可。


【代码】

class Solution {
    
    
public:
    string addBinary(string a, string b) {
    
    
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        string res;
        for (int i = 0, t = 0; i < a.size() || i < b.size() || t; i++)
        {
    
    
            if (i < a.size()) t += a[i] - '0';
            if (i < b.size()) t += b[i] - '0';
            res += to_string(t % 2);
            t /= 2;
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

LeetCode 68. 文本左右对齐(困难)

【题目描述】

给定一个单词数组 words 和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用贪心算法来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。

注意:

  • 单词是指由非空格字符组成的字符序列。
  • 每个单词的长度大于 0,小于等于 maxWidth
  • 输入单词数组 words 至少包含一个单词。

【示例1】

输入: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16
输出:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]

【示例2】

输入:words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16
输出:
[
  "What   must   be",
  "acknowledgment  ",
  "shall be        "
]
解释: 注意最后一行的格式应为 "shall be    " 而不是 "shall     be",
     因为最后一行应为左对齐,而不是左右两端对齐。       
     第二行同样为左对齐,这是因为这行只包含一个单词。

【示例3】

输入:words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"],maxWidth = 20
输出:
[
  "Science  is  what we",
  "understand      well",
  "enough to explain to",
  "a  computer.  Art is",
  "everything  else  we",
  "do                  "
]

【提示】

1 ≤ w o r d s . l e n g t h ≤ 300 1\le words.length\le 300 1words.length300
1 ≤ w o r d s [ i ] . l e n g t h ≤ 20 1\le words[i].length\le 20 1words[i].length20
words[i] 由小写英文字母和符号组成
1 ≤ m a x W i d t h ≤ 100 1\le maxWidth\le 100 1maxWidth100
w o r d s [ i ] . l e n g t h ≤ m a x W i d t h words[i].length\le maxWidth words[i].lengthmaxWidth

【分析】


假设我们有 t t t 个空格需要添加,有 c c c 个空位,由于需要尽可能平均地分配空格,因此每个空位至少需要有 ⌊ t c ⌋ \lfloor \frac{t}{c} \rfloor ct 个空格,多出来的不能均匀分配的 t % c t\% c t%c 个空格从左边开始依次加到每个空位中(每个空位加一个空格)。

还有需要注意当一行只有一个单词或者为最后一行时需要左对齐,在右边填充空格即可。


【代码】

class Solution {
    
    
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
    
    
        vector<string> res;
        for (int i = 0; i < words.size(); i++)
        {
    
    
            int len = words[i].size();  // 当前行的总长度,每个单词间有一个空格
            int j = i + 1;  // 一行能够放置最多单词的右边界
            while (j < words.size() && len + 1 + words[j].size() <= maxWidth)
                len += 1 + words[j].size(), j++;
            string line;
            if (j == i + 1 || j == words.size())  // 只有一个单词或者最后一行
            {
    
    
                line += words[i];
                for (int k = i + 1; k < j; k++) line += ' ' + words[k];
                while (line.size() < maxWidth) line += ' ';  // 长度不够在右边补空格
            }
            else  // 否则需要两端对齐
            {
    
    
                int c = j - i - 1, t = maxWidth - len + c;  // c表示空位数,t表示需要填充的空格数
                int k = 0;
                while (k < t % c) line += words[i + k] + string(t / c + 1, ' '), k++;
                while (k < c) line += words[i + k] + string(t / c, ' '), k++;
                line += words[i + k];  // 最后一个单词
            }
            res.push_back(line);
            i = j - 1;
        }
        return res;
    }
};

LeetCode 69. x 的平方根(简单)

【题目描述】

给你一个非负整数 x,计算并返回 x算术平方根
由于返回类型是整数,结果只保留整数部分 ,小数部分将被舍去
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

【示例1】

输入:x = 4
输出:2

【示例2】

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

【提示】

0 ≤ x ≤ 2 31 − 1 0\le x\le 2^{31}-1 0x2311

【分析】


二分答案模板题,找出 y 2 ≤ x y^2\le x y2x 的最大的 y y y 即可,即我们每次在 0 ∼ x 0\sim x 0x 区间中二分出 m i d mid mid,判断 m i d mid mid 是否大于等于 x x x


【代码】

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        int l = 0, r = x;
        while (l < r)
        {
    
    
            int mid = l + 1ll + r >> 1;  // 1ll防止l + r溢出
            // mid * mid <= x中可能会溢出,因此需要移一下位
            if (mid <= x / mid) l = mid;
            else r = mid -  1;
        }
        return r;
    }
};

LeetCode 70. 爬楼梯(简单)

【题目描述】

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

【示例1】

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

【示例2】

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

【提示】

1 ≤ n ≤ 45 1\le n\le 45 1n45

【分析】


假设 f[i] 表示跳到第 i i i 阶台阶的方法数,那么可以从第 i − 2 i-2 i2 i − 1 i-1 i1 阶台阶跳过来,即 f[i] = f[i - 2] + f[i - 1],这个转移方程就是斐波那契数列,因此我们只需要用两个变量循环滚动即可。在起点的方法数为1,第一阶台阶只能从起点跳过来,因此方法数也为1,然后我们往后求解到第 n − 1 n-1 n1 项即可。


【代码】

class Solution {
    
    
public:
    int climbStairs(int n) {
    
    
        int a = 1, b = 1;
        while (--n)  // --n只循环n-1次
        {
    
    
            int c = a + b;
            a = b, b = c;
        }
        return b;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_51755720/article/details/133303250