业余时间做一些题。
第一反应是用双重 for 循环,可是 O(N^2)的复杂度通不过校验,就改成如下方法了,时间复杂度为O(N)。
思路:
1、遍历数组,用 target 减去 nums[i] 得到差值,判断得到的差值是否在剩余的元素中(nums.slice(i+1))。
2、如果差值存在于数组中,就将 i 和 k(差值在剩余的元素中的索引)+ i + 1 push 进 result。
/** * @param {number[]} nums * @param {number} target * @return {number[]} */var twoSum = function(nums, target) { var i, k, diffIndex, len = nums.length, result = []; for(i = 0; i < len - 1; i++){ k = i+1; diffIndex = nums.slice(k).indexOf(target - nums[i]); if(diffIndex !== -1){ result.push(i, diffIndex + i + 1); } } return result;};
题目概览:
给出两个链表,然后计算两个链表的和。题目要求链表中每个节点包的数值都是一位的,高位需要加入到下一个节点中。
题目自带一个链表类的构造函数
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
分析:
其实这个题目,就是简单的加法。只不过我们数学中的加法是从右往左算,它是从左往右算。
如下所示:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8Input: (9 -> 9) + (1)
Output: 0 -> 0 -> 1Input: (3 -> 7) + (9, 4)
Output: 2 -> 2 -> 1思路:
1、new 一个空节点,对应着链表的头部,并赋值给一个临时变量 tempNode, tempNode 的作用是存储新节点。
2、while 循环,当 链表1 和 链表2 任意一个不为空时,执行循环中的代码。
3、把当前节点的 val 相加,注意 两个 val值的和大于10时,需要把高位加入到下一节点。
4、new 一个新节点,参数为上一步骤两个val的值取余10。
5、临时变量 tempNode 的 next 指向 新节点,然后再把 新节点 赋值给 tempNode, 这样的话,下次访问 tempNode.next ,就是访问新节点的 next 了。
6、链表1 和 链表2 移动到各自的下一个节点。回到第2步。
7、如果遍历完 2 个链表,最后的两个 val 值大于 10 的话,需要再 new 一个新节点。
8、妈蛋感觉自己的表达能力不够好,具体可以看文档
代码:
/** * @param {ListNode} l1 * @param {ListNode} l2 * @return {ListNode} */var addTwoNumbers = function(l1, l2){ var l3 = new ListNode(), //空节点 tempNode = l3, tempVal1 = 0, tempVal2 = 0, sum = 0, carry = 0; while(l1 !== null || l2 !== null){ tempVal1 = l1 !== null ? l1.val : 0; tempVal2 = l2 !== null ? l2.val : 0; sum = carry + tempVal1 + tempVal2; carry = parseInt( sum / 10 ); //例如 sum = 4 + 6, 则 sum / 10 等于 1, 下一位数字需要加 1。 tempNode.next = new ListNode( sum % 10 ); tempNode = tempNode.next; //把新节点赋值给 tempNode if(l1 !== null) l1 = l1.next; if(l2 !== null) l2 = l2.next; } //如果最后一个节点后,carry > 0, 则再添加一个节点 if(carry > 0){ tempNode.next = new ListNode( carry ); } return l3.next;};