继昨天的问题,更换思路,使用链表边遍历边相加的思路。
首先在不考虑进位的情况下,完成边遍历边相加的功能。其次再考虑进位的情况。
/**
*
* @param {ListNode} l1
* @param {ListNode} l2
* return {ListNode}
*/
var addTwoNumbers = (l1, l2) => {
// 创建头指针
let result = new ListNode(null);
let head = result;
// 遍历链表,同时遍历l1,l2
while (l1 != null || l2 != null) {
let temp1 = l1 != null ? l1.val : 0;
let temp2 = l2 != null ? l2.val : 0;
// 创建子节点
head.next = new ListNode(temp1 + temp2);
// 移动头指针
head = head.next;
// 移动参数链表指针
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
return result.next;
};
进位的难点其实在于最高位进位时,我们需要再创建一个子节点。
/**
*
* @param {ListNode} l1
* @param {ListNode} l2
* return {ListNode}
*/
var addTwoNumbers = (l1, l2) => {
// 创建头指针
let result = new ListNode(null);
let head = result;
// 进位
let carry = 0;
while (l1 != null || l2 != null) {
let temp1 = l1 != null ? l1.val : 0;
let temp2 = l2 != null ? l2.val : 0;
// 带进位加
let sum = temp2 + temp1 + carry;
// 计算进位
carry = Math.floor(sum / 10);
// 创建子节点
head.next = new ListNode(sum % 10);
// 移动头指针
head = head.next;
// 移动参数链表指针
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
// 如果最高位有进位,则需要多创建一个节点。
if (carry > 0) {
head.next = new ListNode(carry);
}
return result.next;
};
提交结果也是很满意。题目一开始就在强调链表操作,本想取巧使用字符串的操作方式(其实是把链表的知识忘没了),所以还得努力啊。
第三题
无重复字符的最长子串
Category | Difficulty | Likes | Dislikes |
---|---|---|---|
algorithms | Medium (32.04%) | 2737 | - |
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
思路,遍历字符串,用中间变量存储子串,判断每个字符是否存在于中间变量中,如果存在,截取字符串。
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
// 字符串长度
let len = s.length;
// 子串长度
let count = 0;
// 中间字符串
let tempStr = '';
for (let i = 0; i < len; i++) {
if (tempStr.indexOf(s[i]) == -1) {
// 如果当前字符不存在,把字符添加到中间字符串中
tempStr += s[i];
// 如果中间字符串长度大于子串长度,更新子串长度
if (tempStr.length > count) {
count = tempStr.length;
}
} else {
// 如果当前字符存在
tempStr += s[i];
// 找到当前字符在原字符串中的位置
let index = tempStr.indexOf(s[i]);
// 截取原字符串
tempStr = tempStr.slice(index + 1);
}
}
return count;
};
时间效率上还是不错的,但是空间上的占用还是比较的多。