- Add Two Numbers II:题目链接
基本思想:
题目要求不能用逆转链表的方法,那么就用栈充当容器相当于逆转了链表,从各位开始算起,模拟手算的过程
方法1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ typedef struct { struct ListNode * pTop; }LinkStack;
LinkStack * createStack(){ LinkStack *pS = (LinkStack *) malloc(sizeof(LinkStack)); pS->pTop = NULL; return pS; }
void push(LinkStack * pS, int val){ struct ListNode *pNew = (struct ListNode *) malloc(sizeof(struct ListNode )); pNew->val = val; pNew->next = pS->pTop; pS->pTop = pNew; }
int pop(LinkStack * pS){ struct ListNode *pTemp = pS->pTop; int popData = pTemp->val; pS->pTop = pTemp->next; free(pTemp); return popData; }
int emptyStack(LinkStack * pS){ return NULL == pS->pTop; }
struct ListNode *addTwoNumbers(struct ListNode *l1, struct ListNode *l2) { LinkStack *stack_1 = createStack(); // 此栈存放 l1链表 LinkStack *stack_2 = createStack(); // 此栈存放 l2链表 LinkStack *stack_sum = createStack(); // 此栈存放结果 // 建虚拟头结点 指针域记得置NULL struct ListNode *dummy = (struct ListNode *) malloc(sizeof(struct ListNode)); dummy->next = NULL; struct ListNode *curNode_1 = l1, *curNode_2 = l2, *pTail = dummy; // 将l1中所有节点 入栈 7 2 4 3 入栈变成 3 4 2 7 while (curNode_1) { push(stack_1, curNode_1->val); curNode_1 = curNode_1->next; } // 将l2中所有节点 入栈 while (curNode_2) { push(stack_2, curNode_2->val); curNode_2 = curNode_2->next; }
int sum = 0, carry = 0; // 两个栈都不为空 则将其栈顶元素 + 进位 入stack_sum栈 while (!emptyStack(stack_1) && !emptyStack(stack_2)) { sum = pop(stack_1) + pop(stack_2) + carry; carry = sum / 10; push(stack_sum, sum % 10); } // 如果stack_1不空 stack_2空 while (!emptyStack(stack_1)) { sum = pop(stack_1) + carry; carry = sum / 10; push(stack_sum, sum % 10); } // 如果stack_2不空 stack_1空 while (!emptyStack(stack_2)) { sum = pop(stack_2) + carry; carry = sum / 10; push(stack_sum, sum % 10); } // 当遍历到最后两个数 相加时 其值 >= 10 if (carry > 0) { push(stack_sum, carry); } // 将stack_sum中的元素出栈 加入到链表dummy中 从 7 0 8 7变成 7 8 0 7 while (!emptyStack(stack_sum)){ struct ListNode *pNew = (struct ListNode *) malloc(sizeof(struct ListNode)); pNew->val = pop(stack_sum); pNew->next = NULL; pTail->next = pNew; pTail = pNew; } return dummy->next; }
|
方法2:在之前的基础上 优化
- 不需要利用stack_sum 直接使用从头部插入节点的建立链表方式
- 将两个栈空 一个栈空 最后两个数进位为1 等情况整合起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ typedef struct { struct ListNode * pTop; }LinkStack;
LinkStack * createStack(){ LinkStack *pS = (LinkStack *) malloc(sizeof(LinkStack)); pS->pTop = NULL; return pS; }
void push(LinkStack * pS, int val){ struct ListNode *pNew = (struct ListNode *) malloc(sizeof(struct ListNode )); pNew->val = val; pNew->next = pS->pTop; pS->pTop = pNew; }
int pop(LinkStack * pS){ struct ListNode *pTemp = pS->pTop; int popData = pTemp->val; pS->pTop = pTemp->next; free(pTemp); return popData; }
int emptyStack(LinkStack * pS){ return NULL == pS->pTop; }
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) { LinkStack *stack_1 = createStack(); // 此栈存放 l1链表 LinkStack *stack_2 = createStack(); // 此栈存放 l2链表 // 建虚拟头结点 指针域记得置NULL struct ListNode *dummy = (struct ListNode *) malloc(sizeof(struct ListNode)); dummy->next = NULL; struct ListNode *curNode_1 = l1, *curNode_2 = l2, *pTail = dummy; // 将l1中所有节点 入栈 7 2 4 3 入栈变成 3 4 2 7 while (curNode_1) { push(stack_1, curNode_1->val); curNode_1 = curNode_1->next; } // 将l2中所有节点 入栈 while (curNode_2) { push(stack_2, curNode_2->val); curNode_2 = curNode_2->next; }
int sum = 0, carry = 0; // 改进: 将两个栈空 一个栈空 最后两个数进位为1 等情况整合起来 while (!emptyStack(stack_1) || !emptyStack(stack_2) || carry != 0) { int val_1 = emptyStack(stack_1) ? 0 : pop(stack_1); int val_2 = emptyStack(stack_2) ? 0 : pop(stack_2); sum = val_1 + val_2 + carry; carry = sum / 10; struct ListNode *pNew = (struct ListNode *) malloc(sizeof(struct ListNode)); pNew->val = sum % 10; pNew->next = dummy->next; dummy->next = pNew; } return dummy->next; }
|
方法3:利用两个栈 + 头插法的链表
基本思想:
将两个链表分别压入栈中,然后出栈将结果用头插法放到结果链表中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
typedef struct { struct ListNode * pTop; }LinkStack;
LinkStack * createStack(){ LinkStack *pS = (LinkStack *) malloc(sizeof(LinkStack)); pS->pTop = NULL; return pS; }
void push(LinkStack * pS, int val){ struct ListNode *pNew = (struct ListNode *) malloc(sizeof(struct ListNode )); pNew->val = val; pNew->next = pS->pTop; pS->pTop = pNew; }
int pop(LinkStack * pS){ struct ListNode *pTemp = pS->pTop; int popData = pTemp->val; pS->pTop = pTemp->next; free(pTemp); return popData; }
int emptyStack(LinkStack * pS){ return NULL == pS->pTop; }
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){ LinkStack * stack1 = createStack(); LinkStack * stack2 = createStack(); struct ListNode* head = (struct ListNode* ) malloc (sizeof(struct ListNode)); head = NULL; int sum = 0, carry = 0; struct ListNode* cur1 = l1, * cur2 = l2; while (cur1 != NULL) { push(stack1, cur1->val); cur1 = cur1->next; } while (cur2 != NULL) { push(stack2, cur2->val); cur2 = cur2->next; } while (emptyStack(stack1) == 0 && emptyStack(stack2) == 0 ) { int top1 = pop(stack1); int top2 = pop(stack2); sum = top1 + top2 + carry; carry = sum / 10; struct ListNode* newNode = (struct ListNode* ) malloc (sizeof(struct ListNode)); newNode->val = sum % 10; newNode->next = head; head = newNode; } while (emptyStack(stack1) == 0 ) { int top1 = pop(stack1); sum = top1 + carry; carry = sum / 10; struct ListNode* newNode = (struct ListNode* ) malloc (sizeof(struct ListNode)); newNode->val = sum % 10; newNode->next = head; head = newNode; } while ( emptyStack(stack2) == 0) { int top2 = pop(stack2); sum = top2 + carry; carry = sum / 10; struct ListNode* newNode = (struct ListNode* ) malloc (sizeof(struct ListNode)); newNode->val = sum % 10; newNode->next = head; head = newNode; } if (carry > 0) { struct ListNode* newNode = (struct ListNode* ) malloc (sizeof(struct ListNode)); newNode->val =carry; newNode->next = head; head = newNode; } return head; }
|
pS:
源代码链接