每日一练JS

45 阅读2分钟

无重复字符的最长子串(给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 比如s1 = "abcabcbb" abc最长为3)

哈希(new Map)

var func = function(s){
    const map = new Map();
    let start = 0,maxLen = 0;
    for(let i = 0;i<s.length;i++){
        if(map.has(s[i]){
        start = Math.max(start,map.get(s[i] + 1)); //这里是 若发现在字符串有重复的了 更新下 这个开始的位置
        }
        map.set(s[i],i); //set 进去这个map 哈希表里,若set 有重复 新的会覆盖旧的
        maxLen = Math.max(maxLen,i-start+1) //实时更新一下  最大长度
    }
    return maxLen;
}

寻找两个正序数组的中位数 (给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。)

    var func = function(nums1,nums2){
        //先合并两个数组 并做 一下排序
        let merged = nums1.concat(nums2).sort((a,b)=>a-b);
        const len = merged.length;
        //判断长度的值 奇偶性 ,若是 偶数 即是 中间两位数的平均数 ;若是 奇数 取 z中间的数
        if(len%2===0){
            return (merged[len/2] +merged[len/2-1])/2;
         }else{
             return merged[Math.floor(len/2)]
         }
        
     }
但是 有一个问题 他不满足 时间复杂度 为O(log(m+n))的条件

考虑,第二个方案

    function func(nums1, nums2) {
    // 确保 nums1 是较短的数组  这确保我们总是在较短的数组 nums1 上执行二分搜索,以优化时间复杂度。 使用的是 数组解构
    if (nums1.length > nums2.length) {
        [nums1, nums2] = [nums2, nums1];
    }
    /* m 和 n 分别是 nums1 和 nums2 的长度。
imin 和 imax 是 nums1 上的二分搜索边界。
halfLen 是总元素数量的一半(上取整)。*/
    const m = nums1.length;
    const n = nums2.length;
    let imin = 0, imax = m, halfLen = Math.floor((m + n + 1) / 2);
    // 开始二分法搜索
    while (imin <= imax) {
        // 确定分割点 在 nums1 中,i 是分割点。
        // j 是 nums2 中的分割点,它是基于 halfLen 和 i 计算的。
        const i = Math.floor((imin + imax) / 2);
        const j = halfLen - i;
        // 调整二分搜索边界: 这里的目标是调整 i 的值,使得 nums1[i-1] <= nums2[j] 并且 nums2[j-1] <= nums1[i]。
        if (i < m && nums1[i] < nums2[j - 1]) {
            // Increase i
            imin = i + 1;
        } else if (i > 0 && nums1[i - 1] > nums2[j]) {
            // Decrease i
            imax = i - 1;
        } else {
            // i is perfect
            let maxOfLeft = 0;
            if (i === 0) {
                maxOfLeft = nums2[j - 1];
            } else if (j === 0) {
                maxOfLeft = nums1[i - 1];
            } else {
                maxOfLeft = Math.max(nums1[i - 1], nums2[j - 1]);
            }

            if ((m + n) % 2 === 1) {
                return maxOfLeft;
            }
            let minOfRight = 0;
            if (i === m) {
                minOfRight = nums2[j];
            } else if (j === n) {
                minOfRight = nums1[i];
            } else {
                minOfRight = Math.min(nums1[i], nums2[j]);
            }

            return (maxOfLeft + minOfRight) / 2.0;
        }
    }
    return 0.0;
}