Leetcode编程练习(C++实现)

7、反转整数

/*
    题目描述: 给定一个 32 位有符号整数,将整数中的数字进行反转。

    基本思想:
    1、类似于字符串的逆置,取x的最低位(个位)数字:pop = x % 10;
    2、求结果: rev = rev * 10 + pop;
    3、将 x 更新为: x = x / 10;
    4、重复1~3步骤,直至 x == 0

    注意:
    1、进行有效性检查
    2、rev = rev * 10 + pop 可能会导致溢出,因此要对 rev 进行有效性检查
    a)、当 rev > INT_MAX / 10 或者 rev < INT_MIN / 10时,rev 在更新值后必然溢出;
    b)、当 rev = INT_MAX / 10 时,只有当 pop > 7 才会溢出;
    c)、当 rev = INT_MIN / 10 时,只有当 pop < -8 才会溢出
*/
#include "stdafx.h"
#include <iostream>
using namespace std;
int reverse(int x);

int main()
{
    //从控制台输入一个整数
    cout << "Enter a integer: ";
    int number;
    cin >> number;
    cout << reverse(number) << endl;
    return 0;
}

int reverse(int x)
{
    if (x > INT_MAX || x < INT_MIN)
        return 0;
    int rev = 0;
    while (x != 0)
    {
        int pop = x % 10;
        if (rev > INT_MAX / 10 || (rev == INT_MAX && pop > 7))
            return 0;
        if (rev < INT_MIN / 10 || (rev == INT_MIN && pop < -8))
            return 0;
        rev = rev * 10 + pop;
        x /= 10;
    }
    return rev;
}

 8、字符串转整数(atoi)

/*
    题目描述:将字符串转为整数

    说明:遍历字符串的每一个字符
    1、从字符串的第一个字符开始找到第一个非空格字符,如果第一个非空字符是正号或负号,选取该符号,
       并将其与后面尽可能多的连续的数字组合起来,这部分字符即为整数的值;
    2、如果第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数;
    3、字符串可以在形成整数的字符后面包括多余的字符,这些字符可以被忽略,它们对于函数没有影响;
    4、当字符串中的第一个非空字符序列不是个有效的整数;或字符串为空;或字符串仅包含空白字符时,则不进行转换,返回 0
*/

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

int myAutoi(string str);

int main()
{
    cout << "Enter a string: ";
    string str;
    cin >> str;
    cout << myAutoi(str);
    return 0;
}

int myAutoi(string str)
{
    long result = 0;
    int i = 0;
    int sign = 1;

    while (str[i] == ' ')
        i++;

    if (str[i] == '-')
    {
        sign = -1;
        i++;
    }
    else if (str[i] == '+')
    {
        sign = 1;
        i++;
    }
    while (str[i] != '\0')
    {
        if (str[i] < '0' || str[i] > '9')
            break;
        result = result * 10 + sign * (str[i] - '0');
        i++;
    }
    if (result < INT_MIN)
        return INT_MIN;
    else if (result > INT_MAX)
        return INT_MAX;
    else
        return result;
}

 11、盛最多水的容器

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

    解决方案:
    1、暴力法:将数组中的数字两两组合构成一个矩形容器,求出盛水体积,保存最大值;
    2、双指针法:
       这种方法背后的思路在于,两线段之间形成的区域总是会受到其中较短那条长度的限制。
       此外,两线段距离越远,得到的面积就越大。我们在由线段长度构成的数组中使用两个指针,一个放在开始,一个置于末尾。 
       此外,我们会使用变量 maxArea 来持续存储到目前为止所获得的最大面积。 
       在每一步中,我们会找出指针所指向的两条线段形成的区域,更新 maxArea,并将指向较短线段的指针向较长线段那端移动一步。

*/
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;

int maxArea1(vector<int> & height);        //暴力法
int maxArea2(vector<int> & height);        //双指针法

int main()
{
    return 0;
}

int maxArea1(vector<int> & height)
{
    int max = 0;
    for (int i = 0; i < height.size(); i++)
    {
        for (int j = i + 1; j < height.size(); j++)
        {
            int temp = (j - i) * (height[i] < height[j] ? height[i] : height[j]);
            max = max > temp ? max : temp;
        }
    }
    return max;
}

int maxArea2(vector<int> & height)
{
    int maxArea = 0;
    int i = 0, j = height.size() - 1;
    while (i < j)
    {
        int temp = (j - i) * (height[i] < height[j] ? height[i] : height[j]);
        maxArea = maxArea > temp ? maxArea : temp;
        if (height[i] < height[j])
            i++;
        else
            j--;
    }
    return maxArea;
}

 17、电话号码的字母组合,基本思想:回溯法

class Solution {
public:
    string words[10] = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
    vector<string> letterCombinations(string digits)
  { vector
<string> v; if (digits.length() == 0) return v; else { string ss = ""; findstring(ss, digits, 0, v); } return v; } void findstring(string & s, string digits, unsigned int p, vector<string> & v) { if (p == digits.size()) { //递归结束,将字符串 s 添加到 v 中 v.push_back(s); return; } else { for (unsigned int i = 0; i < words[digits[p] - '0'].size(); i++) { s = s + words[digits[p] - '0'][i]; findstring(s, digits, p + 1, v); s.pop_back(); } } } };

 21、合并两个有序链表

/*
    题目描述:合并两个有序链表
*/

#include "stdafx.h"
using namespace std;

struct ListNode
{
    int val;
    ListNode * next;
    ListNode(int x) : val(x), next(nullptr) {}
};

ListNode * mergeTwoLists(ListNode * l1, ListNode * l2);

int main()
{
    return 0;
}

ListNode * mergeTwoLists(ListNode * l1, ListNode * l2)
{
    ListNode * l = new ListNode(0);
    ListNode * r = l;
    ListNode * p = l1;
    ListNode * q = l2;
    while (p != nullptr && q != nullptr)
    {
        if (p->val < q->val)
        {
            ListNode * s = new ListNode(p->val);
            r->next = s;
            r = r->next;
            p = p->next;
        }
        else
        {
            ListNode * s = new ListNode(q->val);
            r->next = s;
            r = r->next;
            q = q->next;
        }
    }

    while (p != nullptr)
    {
        ListNode * s = new ListNode(p->val);
        r->next = s;
        r = r->next;
        p = p->next;
    }

    while (q != nullptr)
    {
        ListNode * s = new ListNode(q->val);
        r->next = s;
        r = r->next;
        q = q->next;
    }

    l = l->next;
    return l;
}

 

posted @ 2018-10-31 20:31  SChenqi  阅读(420)  评论(0编辑  收藏  举报