版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/solopointer/article/details/51378858
题目大意:
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode * head = nullptr, *tail = nullptr;
bool jw = false;
while (l1 || l2)
{
int sum = jw ? 1 : 0;
if (l1)
sum += l1->val, l1 = l1->next;
if (l2)
sum += l2->val, l2 = l2->next;
if (nullptr == head)
head = tail = new ListNode(sum % 10);
else
tail->next = new ListNode(sum % 10), tail = tail->next;
jw = sum >= 10;
}
tail->next = jw ? new ListNode(1) : nullptr;
return head;
}
寻思为什么如此低效,看了一下讨论 原来可以添加一个对特殊情况的优化,即如果有其中一个列表为空,则直接返回另外一个列表即可
优化后的代码如下:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if (nullptr == l1)
return l2;
if (nullptr == l2)
return l1;
ListNode * head = nullptr, *tail = nullptr;
bool jw = false;
while (l1 || l2)
{
int sum = jw ? 1 : 0;
if (l1)
sum += l1->val, l1 = l1->next;
if (l2)
sum += l2->val, l2 = l2->next;
if (nullptr == head)
head = tail = new ListNode(sum % 10);
else
tail->next = new ListNode(sum % 10), tail = tail->next;
jw = sum >= 10;
}
tail->next = jw ? new ListNode(1) : nullptr;
return head;
}
发现测试结果变成了几百64.7%的提交
继续优化:
发现传入的参数未添加const标识符,如果假设实参是可以在函数内部改变的,那么就可以直接用较长的一个链表作为基础,将短列表叠加到长列表上,这样就不需要申请内存了:
class Solution2 {
public:
unsigned int GetListSize(const ListNode * head)
{
unsigned int res = 0;
while (head != nullptr)
++res, head=head->next;
return res;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if (nullptr == l1)
return l2;
if (nullptr == l2)
return l1;
ListNode * main = nullptr,* result=nullptr,* other=nullptr;
if (GetListSize(l1) > GetListSize(l2))
main = result = l1, other = l2;
else
main = result = l2, other = l1;
bool jw = false;
while (main)
{
main->val += (other?other->val:0)+(jw?1:0);
jw = main->val >= 10;
main->val %= 10;
other = other?other->next:nullptr;
if (nullptr == main->next)
{
main->next = jw ? new ListNode(1) : nullptr;
break;
}
else
main = main->next;
}
main->next = jw ? new ListNode(1) : nullptr;
return result;
}
};
发现效果很不明显,这次打败了63.7%的提交,继续优化:发现如果累加到中间如果短链表已经到头了,而且没有进位,那么即可以直接结束算法,代码如下:
class Solution2 {
public:
unsigned int GetListSize(const ListNode * head)
{
unsigned int res = 0;
while (head != nullptr)
++res, head=head->next;
return res;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if (nullptr == l1)
return l2;
if (nullptr == l2)
return l1;
ListNode * main = nullptr,* result=nullptr,* other=nullptr;
if (GetListSize(l1) > GetListSize(l2))
main = result = l1, other = l2;
else
main = result = l2, other = l1;
bool jw = false;
while (main)
{
main->val += (other?other->val:0)+(jw?1:0);
jw = main->val >= 10;
main->val %= 10;
other = other?other->next:nullptr;
if (other == nullptr&&jw == false)
break;
if (nullptr == main->next)
{
main->next = jw ? new ListNode(1) : nullptr;
break;
}
else
main = main->next;
}
if(nullptr == main->next)
main->next = jw ? new ListNode(1) : nullptr;
return result;
}
};
效果不是很明显,击败了63.4%的提交
郁闷,真不知道剩下的36.6%是使用了什么优化,这么牛逼,看来还有待继续优化