Leetcode第二题 两数相加 C语言版

由于我们学院(没错就是信通弟弟学院)辅导员的神操作(在我们没学数据结构的情况下要求我们刷力扣)
本人提前了自己的规划,由于自己自学了一点链表的知识,因此想试着找道题练习,于是选择了第二题(以后绝不轻易碰中等题。。。)
在经历了许多次增加,改bug之后,经过敏捷开发的洗礼,3天半的苦战,自己终于做出了这道题,
查看结果,发现并不是很理想,再次将自己的思路和改进的经验分享给大家,也提醒大家,少走弯路。

在这里插入图片描述
首先,代码奉上:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
	struct ListNode *Apply(int x){
		struct ListNode * p,*q;
		p = (struct ListNode *)malloc(sizeof(struct ListNode));
		if (x < 10) {
		p->val = x;
		p->next = NULL;
		return(p);		
		}
		else {
			p->val = x - 10;
			q = (struct ListNode *)malloc(sizeof(struct ListNode));
			q->val = 1;
			q->next = NULL;
			p->next = q;
			return(p);
		}
	}
	//初始化节点(建立表头)
	struct ListNode *InitList(){
		struct ListNode *head;
		head = (struct ListNode *)malloc(sizeof(struct ListNode));
        head->val = 0;
		head->next = NULL;
		return(head);
	}

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
	    struct	ListNode* head, *p, *q,*m,*n;
		p = l1;
  		q = l2;
  		int flag = 0, temp = 0, shi = 0,flag1 = 1;
		head = m = InitList();
		while (p!=NULL && q!=NULL){
			temp = (p->val) + (q->val);
			if (flag != 1) {
				shi = temp >= 10 ? 1 : 0;
				temp = temp - 10 * (temp / 10);//个位
				n = Apply(temp+flag);
				m->next = n;
				m = n;				//尾插法建立新的链表
				flag = shi;
				p = p->next;
				q = q->next;
			}
			else {
				shi = temp >= 9 ? 1 : 0;
				temp = temp + flag >= 10 ? temp+flag-10:temp+flag ;
				n = Apply(temp );
				m->next = n;
				m = n;				//尾插法建立新的链表
				flag = shi;
				p = p->next;
				q = q->next;
			}
		}
    
			while (p!=NULL)//l1未结束l2结束了
			{
				if (flag != 0) {
					while (flag!=0 && p!=NULL)
					{
						if (p == NULL)//********************************
						{
							n = Apply(1);
							m->next = n;
							m = n;
						}
						else {
							if (p->val > 8)
							{
								p->val = p->val + 1 - 10;
								flag = 1;
							n = Apply(p->val);
							m->next = n;
							m = n;
							p = p->next;
							}
							else {
								flag = 0;

							n = Apply(1 + p->val);
							m->next = n;
							m = n;
							p = p->next;
							}
						}				
					}
				}
				else {
					n = Apply( p->val);
					m->next = n;
					m = n;
					p = p->next;
				}
				if (p == NULL && q == NULL && m->val == 0) {    //防止最后出现一个0
				
					m->next = Apply(1);
					p = NULL;
				}
			}
			
			while (q!=NULL)//l2未结束l1结束了
			{
				if (flag != 0) {
					while (flag != 0 && q != NULL)
					{
						if (q == NULL)//********************************
						{
							n = Apply(1);
							m->next = n;
							m = n;
						}
						else {
							if (q->val > 8)
							{
								q->val = q->val + 1 - 10;
								flag = 1;
								n = Apply(q->val);
								m->next = n;
								m = n;
								q = q->next;
							}
							else {
								flag = 0;
								n = Apply(1 + q->val);
								m->next = n;
								m = n;
								q = q->next;
							}
						}
					}
				}
				else {
					n = Apply(q->val);
					m->next = n;
					m = n;
					q = q->next;
				}
				if (p == NULL && q == NULL && m->val == 0) {   //防止最后出现一个0
					m->next = Apply(1);
					q = NULL;
				}
			}
			if (flag != 0) {
				n = Apply(1);
				m->next = n;
				m = n;
				flag = 0;
			}
		return(head->next);
}

自己的体会,零零散散的就

一.大家可以看到,自己为了将建立链表节点的步骤简化,写了两个函数InitList()和Apply(),分别建立头指针和申请新的节点。
二.由于自己只会含有头节点的链表,而题目的是不含有头节点的链表,因此我选择了按照含有头节点,用尾插法做,最后return的时候返回 head->next。

接下来说说自己的改进过程吧:
1.首先,自己解决的就是 342+456 这个问题,自己设置了变量:十位 shi,个位 temp,以及进位标志 flag;完成了第一个题;
2.紧接着,下一个例子 [1,8]+[0] 就难到我了,因为自己没有考虑到位数不同的情况,在查询其他人的答案之后,发现 由于自己while循环的中制条件是 (p!=NULL && q!=NULL) ,因此在退出循环后,如果(p!=NULL),则说明p指向的 l1链表还有剩余元素,也就是 l1没有结束,按照这个思路,自己又写了while(p!=NULL)和while(q!=NULL)的情况,解决了这一问题。
3.然后由于没有考虑到进位,在 [2]+[8,9,9,9] 这个例子又翻车了,自己于是加了个flag进位标志判定。
4.在主循环中依然有[2,1,8]+[8,2,9,9]这个例子翻车。。。。再改进
5.由于自己用的VS2017,显然力扣的编译器功能不那么强大,遇到空指针的应用还是报超时,再改。。。增加空指针判断。。。。
最终就成了这个又臭又长的。。。。
虽然很丑吧,但是思路清晰,我觉的还是很有必要看看别人的,他们怎么能用几十行就写完的啊啊啊啊啊啊(苦.orz)

最后说一句,C语言写的的确很长,不如py或者Java的行数少得多,但是我C的运行快啊,而且内存空间才9MB,很少的(同等8ms的Java用了44MB)

猜你喜欢

转载自blog.csdn.net/QinZheng7575/article/details/97494619
今日推荐