Day Two

继昨天的问题,更换思路,使用链表边遍历边相加的思路。
首先在不考虑进位的情况下,完成边遍历边相加的功能。其次再考虑进位的情况。

/**
 * 
 * @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;
};
image.png

提交结果也是很满意。题目一开始就在强调链表操作,本想取巧使用字符串的操作方式(其实是把链表的知识忘没了),所以还得努力啊。


第三题

无重复字符的最长子串

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;
};

时间效率上还是不错的,但是空间上的占用还是比较的多。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。