leetcode算法训练#2 Add Two Numbers

版权声明:本文为博主原创文章,未经博主允许不得转载。 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

初级版算法只击败了18.87%的提交

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%是使用了什么优化,这么牛逼,看来还有待继续优化


猜你喜欢

转载自blog.csdn.net/solopointer/article/details/51378858