• LeetCode #003# Longest Substring Without Repeating Characters(js描述)


    问题描述:https://leetcode.com/problems/longest-substring-without-repeating-characters/

    思路1:分治策略

    按照算法导论上的分治算法框架强行写的。

    class CommonUtil {
        static lightCopy(obj) {
            let result = {}
            Object.assign(result, obj);
            return result;
        }
    }
    
    // O(???), Runtime: 7792 ms, faster than 1.00% ...
    var lengthOfLongestSubstring = function(s) {
        if (s == "") return 0;
    
        let buildMaps = (symbol, p, q, r) => {
            let map = [],
                length = 0;
            let current = () => q - length;
            if (symbol == "right") {
                current = () => q - 1 + length;
            }
    
            let init = () => { // 创建一个空对象,免去繁琐的初始化过程
                map[length++] = {};
            };
    
            let isSafe = () => { // 越界or字符重复返回false
                let out = symbol == "right" ? current() >= r : current() < p;
                let repeat = map[length - 1][s[current()]];
                return !out && !repeat;
            };
    
            let createMap = () => { // 复制map>>添加元素>>为下次调用做准备
                map[length] = CommonUtil.lightCopy(map[length - 1]);
                map[length][s[current()]] = true;
                length++;
            };
    
            init();
            while (isSafe()) {
                createMap();
            }
            return map;
        };
    
        let combineMaps = (leftMaps, rightMaps, max) => {
            let compatible = (map1, map2) => {
                if (map1.length < map2.length) {
                    let temp = map1;
                    map1 = map2;
                    map2 = temp;
                }
                let keys = Object.keys(map2);
                return !keys.some(x => map1[x]);
            };
    
            let getPairs = (totalReduce) => {
                let reducePairs = [];
                for (let k = 0; k <= totalReduce; ++k) {
                    reducePairs.push({
                        i: k,
                        j: totalReduce - k,
                    });
                }
                return reducePairs;
            };
    
            const leftLen = leftMaps.length - 1,
                rightLen = rightMaps.length - 1,
                baseLen = leftLen + rightLen;
    
            let sum = 0;
            let totalReduce = 0;
            while ((sum = baseLen - totalReduce) > max) {
                // 只检测比子问题解的值更大的情形,由大往小找,一旦找到立刻停止搜索
                let reducePairs = getPairs(totalReduce);
                for (let k = 0; k != reducePairs.length; ++k) {
                    let i = leftLen - reducePairs[k].i;
                    let j = rightLen - reducePairs[k].j;
                    if (i > 0 && j > 0 && compatible(leftMaps[i], rightMaps[j])) {
                        return sum;
                    }
                }
                totalReduce++;
            }
            return max;
        };
    
        let findMaxCrossingSubstring = (p, q, r, subMaxLength) => {
            if (s[q - 1] == s[q]) { // 不可连接
                return subMaxLength;
            } else {
                let leftMaps = buildMaps("left", p, q, r);
                let rightMaps = buildMaps("right", p, q, r);
                return combineMaps(leftMaps, rightMaps, subMaxLength);
            }
        };
    
        let findMax = (start, end) => {
            if (start + 1 < end) {
                let mid = Math.floor((start + end) / 2); // Divide
                let maxLeft = findMax(start, mid); // Conquer
                let maxRight = findMax(mid, end); // Conquer
                const subMaxLength = Math.max(maxLeft, maxRight); // Combine
                return findMaxCrossingSubstring(start, mid, end, subMaxLength); // Combine
            } else {
                return 1; // basecase
            }
        };
    
        return findMax(0, s.length);
    };
    View Code

    思路2:Brute Force - O(n^3)

    let satisfyCondition = (i, j, s) => {
        let map = {};
        for (let k = i; k <= j; ++k) {
            if (map[s[k]]) return false;
            map[s[k]] = true;
        }
        return true;
    };
    
    var lengthOfLongestSubstring2 = function(s) {
        if (s == "") return 0;
        let max = 1,
            length, i, j;
        for (i = 0; i != s.length; ++i) {
            for (j = i + 1; j != s.length; ++j) {
                length = j - i + 1;
                if (length > max) {
                    if (satisfyCondition(i, j, s)) {
                        max = length;
                    } else {
                        break;
                    }
                }
            }
        }
        return max;
    };

    思路3

    var lengthOfLongestSubstring = function(s) {
        if (s.length < 2) return s.length;
        let max = 0, lastBegin = 0, code, characterIndex = new Array(255), fresh;
        for (let i = 0; i !== s.length; ++i) {
            code = s.charCodeAt(i);
            if (characterIndex[code] >= lastBegin) {
                lastBegin = characterIndex[code] + 1;
            }
            fresh = i - lastBegin + 1;
            if (fresh > max) {
                max = fresh;
            }
            characterIndex[code] = i;
        }
        return max;
    };
  • 相关阅读:
    WebView自适应屏幕
    shell脚本:遍历删除
    查看Mysql执行计划
    Spring 源码学习(八) AOP 使用和实现原理
    Java:控制反转(IoC)与依赖注入(DI)
    浏览器-开发者工具
    查看kafka消息消费情况
    shell脚本:遍历删除文本内路径上文件
    聚簇索引与非聚簇索引(也叫二级索引)
    有关MySQL
  • 原文地址:https://www.cnblogs.com/xkxf/p/10230703.html
Copyright © 2020-2023  润新知