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;
}