Task01——采用C++

Task01

题号2:两数相加

题号:2
难度:中等
https://leetcode-cn.com/problems/add-two-numbers/ 3
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

示例 2:

输入:(3 -> 7) + (9 -> 2)
输出:2 -> 0 -> 1
原因:73 + 29 = 102

C++做法:
利用链表的每一位相加,结果大于10时向前进位(还有点小问题有待修正)

class Solution
{
public:
    ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
    {
        ListNode *result = new ListNode();
        int Carry = 0;
        while (l1->next != nullptr && l2->next != nullptr)
        {
            int a = l1->val;
            int b = l2->val;
            Carry = a + b + Carry;
            result->next = new ListNode(Carry % 10);
            result = result->next;
            Carry = Carry / 10;
            l1 = l1->next;
            l2 = l2->next;
        }
        while (l1->next != nullptr)
        {
            Carry = Carry + l1->val;
            result->next = new ListNode(Carry % 10);
            Carry = Carry / 10;
            l1 = l1->next;
            result = result->next;
        }
        while (l2->next != nullptr)
        {
            Carry = Carry + l2->val;
            result->next = new ListNode(Carry % 10);
            Carry = Carry / 10;
            l2 = l2->next;
            result = result->next;
        }
        if (Carry == 1)
            result->next = new ListNode(1);
        return result;
    }
};

题目:寻找两个数组中位数

题号:4
难度:困难
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/ 1
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

C++做法:
思路:采用递归的方法(借鉴的大神的思路,加以自己的理解)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(), n = nums2.size(), left = (m + n + 1) / 2, right = (m + n + 2) / 2;
        return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;
    }
    int findKth(vector<int>& nums1, int i, vector<int>& nums2, int j, int k) {
        if (i >= nums1.size()) return nums2[j + k - 1];
        if (j >= nums2.size()) return nums1[i + k - 1];
        if (k == 1) return min(nums1[i], nums2[j]);
        int midVal1 = (i + k / 2 - 1 < nums1.size()) ? nums1[i + k / 2 - 1] : INT_MAX;
        int midVal2 = (j + k / 2 - 1 < nums2.size()) ? nums2[j + k / 2 - 1] : INT_MAX;
        if (midVal1 < midVal2) {
            return findKth(nums1, i + k / 2, nums2, j, k - k / 2);
        } else {
            return findKth(nums1, i, nums2, j + k / 2, k - k / 2);
        }
    }
};

题目:最长回文子串(未完成,转载别人的)

题号:5
难度:中等
https://leetcode-cn.com/problems/longest-palindromic-substring/
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

示例 3:

输入: "a"
输出: "a"

C++做法:
转载至https://www.cnblogs.com/cicinnus/p/13227577.html
1、暴力解法 时间O(n^3) 空间O(1)

string longestPalindrome(string s) {
    int len = s.length();
    if (len < 2) {
        return s;
    }
    int maxn = 1;
    int idx = 0;
    for (int i = 1; i < len - 1; i++) {
        for (int j = i + 1; j < len; j++) {
            string tmp = s.substr(i, j - i + 1);
            string tmp2 = tmp;
            reverse(tmp.begin(), tmp.end());
            if (tmp == tmp2 && j - i + 1 > maxn) {
                maxn = j - i + 1;
                idx = i;
            }
        }
    }
    return s.substr(idx, maxn);
}

2、动态规划 时间O(n^2) 空间O(n^2)

边界条件

当子串长度为1时,dp[i][i] = true
当子串长度为2时,dp[i][j] = s[i]==s[j]
动态转移方程

dp[i][j] = dp[i+1][j-1] && s[i] == s[j]

string longestPalindrome(string s) {
    int len = s.length();
    if (len < 2) {
        return s;
    }
    int maxn = 1;
    int idx = 0;
    vector<vector<int> > dp(len, vector<int>(len));
    for (int i = 0; i < len; i++) {
        dp[i][i] = 1;
    }
    for (int j = 1; j < len; j++) {
        for (int i = 0; i < j; i++) {
            if (s[i] != s[j]) {
                dp[i][j] = 0;
            }
            else
            {
                if (j - i + 1 < 4) 
                    dp[i][j] = 1;
                else
                    dp[i][j] = dp[i + 1][j - 1];
            }

            if (dp[i][j] && j - i + 1 > maxn) {
                maxn = j - i + 1;
                idx = i;
            }
        }
    }
    return s.substr(idx, maxn);
}

3、中心扩展 时间O(n^2) 空间O(1)

以下标 i 表示的字符为中心点向两端扩展,判断扩展后的字符是否为回文串

回文子串长度为奇数,中心为 s[i]
回文子串长度为偶数,中心为 s[i, i+1]


string longestPalindrome(string s) {
    int len = s.length();
    if (len < 2) {
        return s;
    }
    int maxn = 1;
    int idx = 0;
    
    for (int i = 0; i < len - 1; i++) {
        int oddLen = computeLen(s, i, i);
        int evenLen = computeLen(s, i, i + 1);
        int tempLen = max(oddLen, evenLen);
        if (tempLen > maxn) {
            maxn = tempLen;
            idx = i - (tempLen - 1) / 2;
        }
    }
    return s.substr(idx, maxn);
}

int computeLen(string s, int l, int r) {
    int len = s.length();
    int i = l, j = r;
    while (i >= 0 && j < len) {
        if (s[i] == s[j]) {
            i--; j++;
        }
        else
        {
            break;
        }
    }
    return j - i - 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值