LeetCode-11

LeetCode-11

二叉树还剩几题,接下来以回溯为主要的学习。回溯法可是我的心头大恨。

OK,回溯法学完了,确实长进非常多,接下来学习贪心,贪心的题量说实话也不少。

1078 Bigram 分词

刷题时间:2021-12-26

var findOcurrences = function (text, first, second) {
    const words = text.split(" ");
    const list = [];
    for (let i = 2; i < words.length; i++) {
        if (words[i - 2] === first && words[i - 1] === second) {
            list.push(words[i]);
        }
    }
    return list
};

669 修剪二叉搜索树

刷题时间:2021-12-26

这个有点难,估计我是写不出来的。

var trimBST = function (root, low, high) {
    if (!root) return null;
    if (root.val < low) return trimBST(root.right, low, high);
    if (root.val > high) return trimBST(root.left, low, high);
    root.left = trimBST(root.left, low, high);
    root.right = trimBST(root.right, low, high);
    return root;
};

108 将有序数组转换为二叉搜索树

刷题时间:2021-12-26

简单题,简单写

var sortedArrayToBST = function (nums) {
    const dfs = (left, right) => {
        if (left == right) {
            return new TreeNode(nums[left]);;
        }
        if(left>right){
            return null;
        }
        const mid = Math.floor((left + right) / 2);
        const root = new TreeNode(nums[mid]);
        root.left = dfs(left, mid - 1);
        root.right = dfs(mid + 1, right);
        return root;
    };
    return dfs(0, nums.length - 1);
};

538 把二叉搜索树转换为累加树

刷题时间:2021-12-26

这个思路转换成数组就能够想明白。

var convertBST = function (root) {
    let pre = 0;
    const ReverseInOrder = (cur) => {
        if (cur) {
            ReverseInOrder(cur.right);
            cur.val += pre;
            pre = cur.val;
            ReverseInOrder(cur.left);
        }
    };
    ReverseInOrder(root);
    return root;
};

825 适龄的朋友

刷题时间:2021-12-27

垃圾时间O(n^2)

var numFriendRequests = function (ages) {
    ages.sort((a, b) => b - a);
    const len = ages.length;
    let res = 0;
    for (let i = 0; i < len; i++) {
        const x = ages[i];
        for (let j = i + 1; j < len; j++) {
            const y = ages[j];
            if (y <= 0.5 * x + 7) {
                continue;
            }
            if (y <= 14) break;
            if (x == y) {
                res++;
            }
            res++;
        }
    }
    return res;
};

双指针,O(nlogn)

var numFriendRequests = function (ages) {
    const n = ages.length;
    ages.sort((a, b) => a - b);
    let left = 0,
        right = 0,
        ans = 0;
    for (const age of ages) {
        if (age < 15) {
            continue;
        }
        while (ages[left] <= 0.5 * age + 7) {
            ++left;
        }
        while (right + 1 < n && ages[right + 1] <= age) {
            ++right;
        }
        ans += right - left;
    }
    return ans;
};

216 组合总和 III

刷题时间:2021-12-27

在组合的基础上改的,还不错,空间和速度基本上都是顶格的。

var combinationSum3 = function (k, n) {
    const res = [];
    const backtrack = (arr, index, sum) => {
        if (sum > n || arr.length > k) {
            return;
        }
        if (sum == n && arr.length == k) {
            res.push(arr.slice());
            return;
        }
        for (let i = index; i <= 9 - (k - arr.length) + 1; i++) {
            arr.push(i);
            backtrack(arr, i + 1, sum + i);
            arr.pop();
        }
    };
    backtrack([], 1, 0);
    return res;
};

131 分割回文串

刷题时间:2021-12-27

回溯的模板确实都差不多,这个是不是回文串的时候需要在横向的时候直接比较。

var partition = function (s) {
    const res = [];
    const len = s.length;
    const backtrack = (path, index) => {
        if (index >= len) {
            res.push(path.slice());
            return;
        }
        for (let i = index; i < len; i++) {
            if (!isPalindrome(s, index, i)) continue;
            path.push(s.substring(index, i + 1));
            backtrack(path, i + 1);
            path.pop();
        }
    };

    const isPalindrome = (s, start, end) => {
        for (let i = start, j = end; i < j; i++, j--) {
            if (s[i] != s[j]) {
                return false;
            }
        }
        return true;
    };
    backtrack([], 0);
    return res;
};

93 复原 IP 地址

刷题时间:2021-12-28

这个题目和上面那个确实很像,分割问题确实可以看成组合问题嗷,不知道还能不能再优化一下

var restoreIpAddresses = function (s) {
    const res = [];
    const len = s.length;
    const backtrack = (path, index) => {
        if (path.length >= 4) return;
        if (index >= len && path.length == 4) {
            res.push(path.join('.'));
            return;
        }

        for (let i = index; i < len; i++) {
            if (i - index >= 3 || !isLegal(s, index, i)) continue;

            path.push(s.substring(index, i + 1));
            backtrack(path, i + 1);
            path.pop();
        }
    };
    const isLegal = (s, l, r) => {
        if (r - l > 0 && s[l] == '0') {
            return false;
        }
        for (let i = l; i <= r; i++) {
            if (!(s[i] >= '0' && s[i] <= '9')) {
                return false;
            }
        }
        const num = parseInt(s.substring(l, r + 1));
        if (num > 255 || num < 0) {
            return false;
        }
        return true;
    };
    backtrack([], 0);
    return res;
};

看到一个新的活,这活也太好了吧,有个+str的操作,就会变成数字,太牛了,如果里面有其他的数字,那么就会变成false,不知道哪里来的骚想法。

var restoreIpAddresses = function(s) {
    const res = [], path = [];
    backtracking(0, 0)
    return res;
    function backtracking(i) {
        const len = path.length;
        if(len > 4) return;
        if(len === 4 && i === s.length) {
            res.push(path.join("."));
            return;
        }
        for(let j = i; j < s.length; j++) {
            const str = s.substr(i, j - i + 1);
            if(str.length > 3 || +str > 255) break;
            if(str.length > 1 && str[0] === "0") break;
            path.push(str);
            backtracking(j + 1);
            path.pop()
        }
    }
};

191 递增子序列

刷题时间:2021-12-28

这题不能用上面那些重复的子集II这种来写,因为不能排序,所以序列不是按序的,可以用set来判断之前横向的是否用过了。

使用slice比array.from要快

var findSubsequences = function (nums) {
    const res = [];
    const len = nums.length;
    const path = [];
    const backtrack = (index) => {
        if (path.length >1) {
            res.push(path.slice());
        }
        let arr = [];
        for (let i = index; i < len; i++) {
            if ((path.length && nums[i] < path[path.length - 1]) || arr[nums[i] + 100]) continue;
            path.push(nums[i]);
            arr[nums[i] + 100] = 1;
            backtrack(i + 1);
            path.pop();
        }
    };
    backtrack(0);
    return res;
};

1995 统计特殊四元组

刷题时间:2021-12-29

这个实在是秒,估计我只能想到O(n3)这种方法,这种应该是想不到的。

var countQuadruplets = function (nums) {
    let n = nums.length;
    let ans = 0;
    const cnt = new Map();
    // 这个逆序反倒是关键的部分,这样子只有遍历一遍就行了
    for (let b = n - 3; b >= 1; --b) {
        for (let d = b + 2; d < n; ++d) {
            cnt.set(nums[d] - nums[b + 1], (cnt.get(nums[d] - nums[b + 1]) || 0) + 1);
        }
        for (let a = 0; a < b; ++a) {
            let sum = nums[a] + nums[b];
            if (cnt.has(sum)) {
                ans += cnt.get(sum);
            }
        }
    }
    return ans;
};

332 重新安排行程

刷题时间:2021-12-29

直接复制粘贴抄袭,困难题睡大觉了

var findItinerary = function (tickets) {
    let result = ['JFK'];
    let map = {};

    for (const tickt of tickets) {
        const [from, to] = tickt;
        if (!map[from]) {
            map[from] = [];
        }
        map[from].push(to);
    }
    for (const city in map) {
        // 对到达城市列表排序
        map[city].sort();
    }

    const backtracing = () => {
        if (result.length === tickets.length + 1) {
            return true;
        }
        const lastCityTickets = map[result[result.length - 1]];

        if (!lastCityTickets || !lastCityTickets.length) {
            return false;
        }
        for (let i = 0; i < lastCityTickets.length; i++) {
            let city = lastCityTickets[i];
            // 删除已走过航线,防止死循环
            lastCityTickets.splice(i, 1);
            result.push(city);
            if (backtracing()) {
                return true;
            }
            result.pop();
            lastCityTickets.splice(i, 0, city);
        }
    };
    backtracing();
    return result;
};

846 一手顺子

刷题时间:2021-12-30、

没看懂题目,直接抄了解析

var isNStraightHand = function (hand, groupSize) {
    const n = hand.length;
    if (n % groupSize !== 0) {
        return false;
    }
    hand.sort((a, b) => a - b);
    const cnt = new Map();
    for (const x of hand) {
        cnt.set(x, (cnt.get(x) || 0) + 1);
    }
    for (const x of hand) {
        if (!cnt.has(x)) {
            continue;
        }
        for (let j = 0; j < groupSize; j++) {
            const num = x + j;
            if (!cnt.has(num)) {
                return false;
            }
            cnt.set(num, cnt.get(num) - 1);
            if (cnt.get(num) == 0) {
                cnt.delete(num);
            }
        }
    }
    return true;
};

51 N 皇后

刷题时间:2021-12-30

经典回溯问题,就是判断稍微费点劲,问题不是很大。

var solveNQueens = function (n) {
    const res = [];
    const backtrack = (path, row) => {
        if (row == n) {
            let arr = [];
            path.forEach((row) => {
                arr.push(row.join(''));
            });
            res.push(arr.slice());
            return;
        }
        for (let col = 0; col < n; col++) {
            if (!isValid(path, row, col)) continue;
            path[row][col] = 'Q';
            backtrack(path, row + 1);
            path[row][col] = '.';
        }
    };
    const isValid = (path, row, col) => {
        for (let i = 0; i < row; i++) {
            if (path[i][col] == 'Q') {
                return false;
            }
        }
        for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if (path[i][j] == 'Q') {
                return false;
            }
        }
        for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
            if (path[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    };
    backtrack(
        new Array(n).fill('.').map(() => new Array(n).fill('.')),
        0
    );
    return res;
};

37 解数独

刷题时间:2021-12-30

抄的,多重回溯,感觉非常的爆炸,但看起来还行。

var solveSudoku = function (board) {
    function isValid(row, col, val, board) {
        let len = 9;
        // 行不能重复
        for (let i = 0; i < len; i++) {
            if (board[row][i] === val) {
                return false;
            }
        }
        // 列不能重复
        for (let i = 0; i < len; i++) {
            if (board[i][col] === val) {
                return false;
            }
        }
        let startRow = Math.floor(row / 3) * 3;
        let startCol = Math.floor(col / 3) * 3;

        for (let i = startRow; i < startRow + 3; i++) {
            for (let j = startCol; j < startCol + 3; j++) {
                if (board[i][j] === val) {
                    return false;
                }
            }
        }
        return true;
    }

    function backTracking() {
        for (let i = 0; i < 9; i++) {
            for (let j = 0; j < 9; j++) {
                if (board[i][j] !== '.') continue;
                for (let val = 1; val <= 9; val++) {
                    if (isValid(i, j, `${val}`, board)) {
                        board[i][j] = `${val}`;
                        if (backTracking()) {
                            return true;
                        }
                        board[i][j] = `.`;
                    }
                }
                return false;
            }
        }
        return true;
    }
    backTracking(board);
    return board;
};

507 完美数

刷题时间:2021-12-31

var checkPerfectNumber = function (num) {
    if (num == 1) return false;
    const size = Math.floor(Math.sqrt(num));
    const arr = [1];
    for (let i = 2; i <= size; i++) {
        if (num % i == 0) {
            arr.push(i);
            arr.push(num / i);
        }
    }
    const sum = arr.reduce((prev, curr) => prev + curr, 0);
    if (sum == num) return true;
    return false;
};

455 分发饼干

刷题时间:2021-12-31

居然没做出来,贪心我还是太菜了,思想是小饼干喂胃口小的,也就是要遍历小饼干

var findContentChildren = function (g, s) {
    g.sort((a, b) => a - b);
    s.sort((a, b) => a - b);
    let index = 0;
    for (let i = 0; i < s.length; i++) {
        if (index < g.length && g[index] <= s[i]) {
            index++;
        }
    }
    return index;
};

376 摆动序列

刷题时间:2021-12-31

不是这个也太难了吧,我一开始觉得这种子序列只能通过动态规划来完成,居然考虑峰值就行了。有点难

var wiggleMaxLength = function (nums) {
    if (nums.length == 1) return 1;
    let curDiff = 0; // 当前一对差值
    let preDiff = 0; // 前一对差值
    let result = 1; // 记录峰值个数,序列默认序列最右边有一个峰值
    for (let i = 0; i < nums.length - 1; i++) {
        curDiff = nums[i + 1] - nums[i];
        // 出现峰值
        if ((curDiff > 0 && preDiff <= 0) || (preDiff >= 0 && curDiff < 0)) {
            result++;
            preDiff = curDiff;
        }
    }
    return result;
};

2022 将一维数组转变成二维数组

刷题时间:2022-01-01

元旦快乐题,新年快乐

var construct2DArray = function (original, m, n) {
    const len = original.length;
    if (len != m * n) {
        return [];
    }
    const res = [];
    for (let i = 0; i < m; i++) {
        let tmp = [];
        for (let j = 0; j < n; j++) {
            tmp.push(original[i * n + j]);
        }
        res.push(tmp.slice());
    }
    return res;
};

390 消除游戏

刷题时间:2022-01-02

抽象数学,搞不来。

var lastRemaining = function(n) {
    let a1 = 1, an = n;
    let k = 0, cnt = n, step = 1;
    while (cnt > 1) {
        if (k % 2 === 0) { // 正向
            a1 = a1 + step;
            an = (cnt % 2 === 0) ? an : an - step;
        } else { // 反向
            a1 = (cnt % 2 === 0) ? a1 : a1 + step;
            an = an - step;
        }
        k++;
        cnt = cnt >> 1;
        step = step << 1;
    }
    return a1;
};

134 加油站

刷题时间:2022-01-04

瞎摸摸出来的,看规律的,应该是贪心算法

var canCompleteCircuit = function (gas, cost) {
    const length = gas.length;
    let cnt = 0;
    let max = -Infinity;
    let res = -1;
    for (let i = 0; i < length; i++) {
        if (max < -cnt) {
            res = i;
            max = -cnt;
        }
        cnt += gas[i] - cost[i];
    }
    if (cnt < 0) return -1;
    return res;
};

135 分发糖果

刷题时间:2022-01-04

直接抄袭,不会写,困难贪心,这居然要从左到右,再从右到左两次贪心,双重贪心

var candy = function (ratings) {
    const len = ratings.length;
    const res = new Array(len).fill(1);
    for (let i = 1; i < len; i++) {
        if (ratings[i] > ratings[i - 1]) res[i] = res[i - 1] + 1;
    }
    for (let i = len - 2; i >= 0; i--) {
        if (ratings[i] > ratings[i + 1]) res[i] = Math.max(res[i], res[i + 1] + 1);
    }
    return res.reduce((prev, curr) => prev + curr);
};

860 柠檬水找零

刷题时间:2022-01-04

简单题简单逻辑。

var lemonadeChange = function (bills) {
    let five = 0,
        ten = 0;
    for (let i = 0; i < bills.length; i++) {
        if (bills[i] == 5) five++;
        else if (bills[i] == 10) {
            ten++;

            if (five > 0) five--;
            else return false;
        } else if (bills[i] == 20) {
            if (ten) {
                ten--;
                if (five) {
                    five--;
                } else return false;
            } else if (five >= 3) five -= 3;
            else return false;
        }
    }
    return true;
};

1576 替换所有的问号

刷题时间:2022-01-05

U1S1,今天这道简单题可不简单啊,难得很。

var modifyString = function (s) {
    const n = s.length;
    const arr = [...s];
    for (let i = 0; i < n; ++i) {
        if (arr[i] === '?') {
            for (let j = 0; j < 3; ++j) {
                if ((i > 0 && arr[i - 1] === String.fromCharCode('a'.charCodeAt() + j)) || (i < n - 1 && arr[i + 1] === String.fromCharCode('a'.charCodeAt() + j))) {
                    continue;
                }
                arr[i] = String.fromCharCode('a'.charCodeAt() + j);
                break;
            }
        }
    }
    return arr.join('');
};

406 根据身高重建队列

刷题时间:2022-01-05

这种二维的贪心,需要先确定一个维度进行考量,然后再从另一个维度上考量。第一个考量的维度是按照身高从高到矮的排序,身高相同按照k小的在前面。排完之后遍历,按照k值大小进行插入,因为不会影响其他的。

var reconstructQueue = function (people) {
    people.sort((a, b) => {
        if (b[0] != a[0]) {
            return b[0] - a[0];
        } else {
            return a[1] - b[1];
        }
    });
    const queue = [];
    for(let i = 0; i < people.length; i++) {
        queue.splice(people[i][1], 0, people[i])
    }
    return queue
};

452 用最少数量的箭引爆气球

刷题时间:2022-01-05

这个方法最取巧的地方就是直接修改原数组的【1】,这样子就比较方便,不需要另外再定义变量和新增判断,巴适的很。

var findMinArrowShots = function (points) {
    points.sort((a, b) => a[0] - b[0]);
    let res = 1;
    for (let i = 1; i < points.length; i++) {
        if (points[i][0] > points[i - 1][1]) {
            res++;
        } else {
            points[i][1] = Math.min(points[i][1], points[i - 1][1]);
        }
    }
    return res;
};
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇