18款禁止未成年软件app湘潭关键词优化服务
⭐LeetCode(数学分类) 2. 两数相加——暴力与优化⭐
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
题解:
暴力与优化,暴力即转换为十进制解题,优化即直接在链表上进行操作,模拟十进制即可进行进位;
代码:
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/// 暴力法 转换为十进制
class Solution1 {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode res = new ListNode();// 不用long时由于链表长度可达100会超int 但long依旧超限制long n1 = 0; long n2 = 0;long stand = 1;while(l1 != null){long tmp = l1.val * stand;n1 += tmp;stand *= 10;l1 = l1.next;}stand = 1;while(l2 != null){long tmp = l2.val * stand;n2 += tmp;stand *= 10;l2 = l2.next;}long n = n1 + n2;if(n == 0){res.val = 0;return res;}ListNode head = res;while(n > 0){int tt = (int)(n % 10);ListNode tmp = new ListNode(tt);head.next = tmp;head = head.next;n /= 10;}return res.next;}
}// 最优解 直接在链表上模拟十进制运算进行加法及进位操作
// 难点在于模拟过程需要对进位进行合理处理
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {// 保存最终链表头部的指针ListNode res = new ListNode();// 用于帮助构建res的遍历指针ListNode head = res;// 暂存器 用于l1和l2后面均为null时若前一节点有需要进位的1时则置为一 无该情况默认0int extra = 0;// 标志位 用于标志哪一个链表在退出第一个while后还有多余未遍历的节点boolean f1 = false;boolean f2 = false;// 采用双指针统一遍历 模拟十进制加法 遇到进位需额外处理 直到某一链表遍历完全或均遍历完全则退出模拟while(l1 != null && l2 != null){int n1 = l1.val;int n2 = l2.val;int n = n1 + n2;// 发生进位if(n >= 10){int tmp = n % 10;// 及时进1给高位 若l1后不空可进位到l1下一点 若空进到l2下一点// 若后面均空则进位到暂存器extraif(l1.next != null)l1.next.val++;else if(l2.next != null)l2.next.val++;else extra = 1;ListNode tNode = new ListNode(tmp);head.next = tNode;}// 未进位 直接新增和的节点else{ListNode tNode = new ListNode(n);head.next = tNode;}// head记得要移动head = head.next;// 越界判断 方便while模拟加法过程退出后哪一链表会剩余节点if(l1.next == null && l2.next == null){f1 = true;f2 = true;}else if(l1.next == null){f1 = true;}else if(l2.next == null){f2 = true;}// 固定移动l1 = l1.next;l2 = l2.next;}// 不可直接将余下的直接链接 因可能存在低位向不为null的节点高位+1情况 会导致9->10 故要检查// eg: l1 = [9,9,9,9,9,9,9] l2 = [9,9,9,9] // 不加额外操作输出 [8,9,9,9,10,9,9]// 正确为 [8,9,9,9,0,0,0,1]if(f1 && !f2){if(l2.val == 10){// 标志位 标志l2余下链表是否有东西boolean flag = false;// 若出现上述预测情况 则要进行循环判断 因可能后1进到前1导致前由9->10 故要继续进位while(l2.val == 10){ListNode tNode = new ListNode(0);head.next = tNode;head = head.next;// 后有东西直接进位+1if(l2.next != null){l2 = l2.next;l2.val++;}// 后无东西则创建一新节点即可 同时l2代表遍历完全else{ListNode tmpNode = new ListNode(1);head.next = tmpNode;flag = true;break;}}// 直至余下链表中无10 此时可直接链接if(!flag)head.next = l2;}// 无10 可直接链接else{head.next = l2;}}// 同上else if(!f1 && f2){if(l1.val == 10){// 标志位 标志余下链表是否有东西boolean flag = false;// 若出现上述预测情况 则要进行循环判断 因可能后1进到前1导致前由9->10 故要继续进位while(l1.val == 10){ListNode tNode = new ListNode(0);head.next = tNode;head = head.next;// 后有东西直接进位+1if(l1.next != null){l1 = l1.next;l1.val++;}// 后无东西则创建一新节点即可 同时l1代表遍历完全else{ListNode tmpNode = new ListNode(1);head.next = tmpNode;flag = true;break;}}// 直至余下链表中无10 此时可直接链接if(!flag)head.next = l1;}// 无10 可直接链接else{head.next = l1;}}// 此不存在上述情况 但可能存在extra 故要考虑是否要因进位而多增加一个节点 其val=1else if(f1 && f2){if(extra == 1){ListNode tNode = new ListNode(1);head.next = tNode;}}// res为带头节点的链表 故返回其nextreturn res.next;}
}