c++刷LeetCode

Posted Hensenberg_Posion

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++刷LeetCode相关的知识,希望对你有一定的参考价值。

717-1比特与2比特字符

有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。

现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。

这个题只要看最后一步是跳了一步,还是两步,如果只跳一步就会跳到最后一个位置,但是如果跳两步就会跳到外面去
这题让我知道了要观察处理数据的方式,

/*有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。

现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。*/
#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    bool isOneBitCharacter(vector<int>& bits)
    {   
        int i = 0;
        for (; i < bits.size()-1;)
        {
            if (bits[i] == 0)
                i += 1;    //如果是0,则跳一步,因为如果是0,则只能是1比特字符
            else
            {
                i += 2;   //如果是1,则跳两步,因为如果是1,则只能是2比特字符
            }
        }
        if (i == bits.size() - 1)   //说明最后一步跳的是1,则是1比特字符
            return true;
        else
        {
            return false;
        }
    }
    
};

int main()
{
    vector<int>Check = { 0,1,0 };
    Solution X;
    if (X.isOneBitCharacter(Check))
    {
        cout << "this is true" << endl;
    }
    else {
        cout << "false" << endl;
    }
	return 0;
}

在这里插入图片描述

14.最长公共前缀

这题让我知道了字符串之间是靠第一个不同字母的asii码值大小来进行排序的。
让我灵活用到了子串的获取函数,获取vector容器中的第一个和最后一个元素的函数。
vector容器里面也能够存放字符串,这个得清楚。


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
/* 写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""*/
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs)
    {
        if (strs.empty())
            return string();
        sort(strs.begin(), strs.end());  //字符串排序的原则就是看第一个不相同字符的asii码值的大小,从而第一个字符串和第二个字符串的最长公共前缀就是整个的最长公共前缀
        string first = strs.front();
        string last = strs.back();
        int i;
        for (i = 0; i < first.size(); i++)
        {
            if (first.at(i) != last.at(i))
                break;
        }
        return first.substr(0, i);
    }
};

int main()
{
    vector<string>str1 = { "flow","flower","flast" };
    Solution X;
    cout << X.longestCommonPrefix(str1) << endl;
    return 0;
}

67.二进制求和

class Solution {
public:
    string addBinary(string a, string b) {
        int al = a.size();
        int bl = b.size();
        while (al < bl) //让两个字符串等长,若不等长,在短的字符串前补零,否则之后的操作会超出索引
        {
            a = '0' + a;
            ++al;
        }
        while (al > bl)
        {
            b = '0' + b;
            ++bl;
        }
        for (int j = a.size() - 1; j > 0; --j) //从后到前遍历所有的位数,同位相加
        {
            a[j] = a[j] - '0' + b[j];
            if (a[j] >= '2') //若大于等于字符‘2’,需要进一
            {
                a[j] = (a[j] - '0') % 2 + '0';
                a[j - 1] = a[j - 1] + 1;
            }
        }
        a[0] = a[0] - '0' + b[0]; //将ab的第0位相加
        if (a[0] >= '2') //若大于等于2,需要进一
        {
            a[0] = (a[0] - '0') % 2 + '0';
            a = '1' + a;
        }
        return a;
    }
};

在这里插入图片描述

20.有效的括号

/*给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
 */
#include<iostream>
using namespace std;
#include<string>
#include<stack>

class Solution {
public:
    bool isValid(string s) {
        cin >> s;
        cout << s;
        stack<char>Stack;
        int i;
        if (!s.size() % 2)   //if the length of the string is cardinal number,the answer is wrong.
            return 0;
        for (i = 0; i < s.size() - 1; i++)
        {
            if (s[i] == '(')
                Stack.push(s[i]);
            if (s[i] == '[')
                Stack.push(s[i]);
            if (s[i] == '{')
                Stack.push(s[i]);
            if (s[i] == ')')
            {
                if (Stack.top() == '(')
                    Stack.pop();
                else
                {
                    return 0;
                }
            }
            if (s[i] == ']')
            {
                if (Stack.top() == '[')
                    Stack.pop();
                else
                {
                    return 0;
                }
            }
            if (s[i] == '}')
            {
                if (Stack.top() == '{')
                    Stack.pop();
                else
                {
                    return 0;
                }
            }
            
        }
        if(Stack.empty())
        return true;
    }
};

int main()
{
    Solution S1;
    string s;
    if (S1.isValid(s))
    {
        cout << "success" << endl;
    }
    return 0;
}

258.各位相加

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

示例 :

输入: 38
输出 : 2
解释 : 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。

这题,需要知道如何获取各个位上的值,通过不断除10再取余来获得,并要知道这里使用递归,自己调用自己。

/*给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

示例 :

输入: 38
输出 : 2
解释 : 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。*/

#include<iostream>
using namespace std;


class Solution {
public:
    int addDigits(int num) 
    {
        int temp = 0;
        while (num)
        {
            temp += num % 10;
            num /= 10;
        }
        if (temp >= 10)
        {
            return addDigits(temp);
        }
        else
        {
            return temp;
        }
    }
};

int main()
{
    Solution S;
    cout << S.addDigits(38) << endl;
	return 0;
}

在这里插入图片描述

415.字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

这题我想到的是就是列竖式,逐位相加,所以算之前,先补零,然后字符串的第一位留着最后算,以防越界。
还可以不用补零,直接算,算一位,就将这一位的答案放到一个字符串中去,最后算完之后,将得到的这个字符串反转过来就是我们要的答案。

提示:

num1 和num2 的长度都小于 5100
num1 和num2 都只包含数字 0 - 9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式

/*给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。



提示:

num1 和num2 的长度都小于 5100
num1 和num2 都只包含数字 0 - 9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式*/

#include<iostream>
using namespace std;
#include<string>

class Solution {
public:
    string addStrings(string num1, string num2) {
		while (num1.size()<num2.size())  //补位,使两个字符串位数相同
		{
			num1 = '0' + num1;
		}
		while (num2.size() < num1.size())
		{
			num2 = '0' + num2;
		}
		int i;
		for (i=num1.size()-1;i>0;i--) //从最后一位开始计算,满10进1,第一位不计算最后再做处理,以防越位。
		{
			num1[i] = num1[i] + (num2[i]-'0');
			if (num1[i]-'0' >= 10)
			{
				num1[i] = num1[i] - 10;
				num1[i - 1] += 1;
			}
		}
		if ((num1[0]-'0' )+( num2[0]-'0') >= 10)
		{
			num1[0] = num1[0] + (num2[0] - '0');
			num1[0] -= 10;
			num1 = '1' + num1;
		}
		else
		{
			num1[0] = num1[0] + (num2[0]-'0');
		}
		return num1;
    }
};

int main()
{
	Solution s1;
	cout << s1.addStrings("1", "9") << endl;
}

989.数组形式的整数加法

对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1, 2, 3, 1]。

给定非负整数 X 的数组形式 A,返回整数 X + K 的数组形式。

示例 1:

输入:A = [1, 2, 0, 0], K = 34
输出:[1, 2, 3, 4]
解释:1200 + 34 = 1234
示例 2:

输入:A = [2, 7, 4], K = 181
输出:[4, 5, 5]
解释:274 + 181 = 455
示例 3:

输入:A = [2, 1, 5], K = 806
输出:[1, 0, 2, 1]
解释:215 + 806 = 1021
示例 4:

输入:A = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], K = 1
输出:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
解释:9999999999 + 1 = 10000000000

提示:

1 <= A.length <= 10000
0 <= A[i] <= 9
0 <= K <= 10000
如果 A.length > 1,那么 A[0] != 0*/

我先是将数组里面的数据弄成一个数temp,然后再让这个数加上 k;之后用不断取余的方法将数放入一个新的容器中,再将容器中的数reverse,就能得到我们要的结果,但是如果,数组长度稍微长一点,就很容易超出int类型的范围,因此我们直接一位一位的进行加,并一位一位地放入新的容器中。还有,遍历容器中的数据时,V.size()-1,后面这个-1别忘了,不然很容易越界。

/*对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1, 2, 3, 1]。

给定非负整数 X 的数组形式 A,返回整数 X + K 的数组形式。



示例 1:

输入:A = [1, 2, 0, 0], K = 34
输出:[1, 2, 3, 4]
解释:1200 + 34 = 1234
示例 2:

输入:A = [2, 7, 4], K = 181
输出:[4, 5, 5]
解释:274 + 181 = 455
示例 3:

输入:A = [2, 1, 5], K = 806
输出:[1, 0, 2, 1]
解释:215 + 806 = 1021
示例 4:

输入:A = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], K = 1
输出:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
解释:9999999999 + 1 = 10000000000


提示:

1 <= A.length <= 10000
0 <= A[i] <= 9
0 <= K <= 10000
如果 A.length > 1,那么 A[0] != 0*/
#include<iostream>
using namespace std;
#include<vector>
#include<math.h>
#include<algorithm>

class Solution {
public:
    vector<int> addToArrayForm(vector<int>& num, int k) {
        vector<int> res;
        int n = num.size();
        for (int i = n - 1; i >= 0; --i) {
            int sum = num[i] + k % 10;
            k /= 10;
            if (sum >= 10) {
                k++;
                sum -= 10;
            }
            res.push_back(sum);
        }
        for (; k > 0; k /= 10) {
            res.push_back(k % 10);
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

void PrintVector(vector<int>V)
{
    for (vector<int>::iterator it = V.begin(); it != V.end(); it++)
    {
        cout << *it << "  ";
    }
    cout << endl;
}

int main()
{
    vector<int>num;
    int i, temp = 0;
    for (i = 0; i < 10; i++)
    {
        cin >> temp;
        num.push_back(temp);
    }
    PrintVector(num);
    Solution s;
    vector<int>newA=s.addToArrayForm(num, 1);
    PrintVector(newA);
    return 0;
}

441.排列硬币

你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。

给定一个数字 n,找出可形成完整阶梯行的总行数。

n 是一个非负整数,并且在32位有符号整型的范围内

首先想到的就是暴力,能放满一行就+1,直到放不满。

/*你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。

给定一个数字 n,找出可形成完整阶梯行的总行数。

n 是一个非负整数,并且在32位有符号整型的范围内*/

#include<iostream>
using namespace std;
class Solution {
public:
    int arrangeCoins(int n) {
        int column = 1;
        int index = 0;  //放满的行数
        while (n >= column)//n理解为剩下的coin,column是没行要放的硬币数,如果大于就能放满这行。
        {
            n -= column;
            column++;
            index++;
        }
        return index;
    }
   
};
int main()
{
    Solution s;
    cout << s.arrangeCoins(5) << endl;
    return 0;
}

在这里插入图片描述

561.数组拆分

给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如(a1, b1), (a2, b2), …, (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。

返回该 最大总和 。
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9

看例子就可以发现,让数组进行排序之后所分成的数组就能使总和最大

/*给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如(a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。

返回该 最大总和 。
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9

*/


#include<iostream>
以上是关于c++刷LeetCode的主要内容,如果未能解决你的问题,请参考以下文章

为啥 leetcode 上很多题 Java 比 C++ 快

Leetcode刷题(2020/03/20)

刷Leetcode心得

LeetCode——Problem1:two sum

从心出发-刷leetcode写给5年后的自己

xcode怎么刷题