代码片段-LC简单中等题

本文通过多个LeetCode题目展示了数据结构(如二叉树、队列)和算法(如深度优先搜索、广度优先搜索)在解决实际问题中的应用。包括查找二叉树中的堂兄弟节点、计算机器人在矩阵中的移动范围、寻找最长回文子串、合并区间以及在数组调整后找到最大元素等。每个问题的解决方案都体现了不同的思路和技巧。
摘要由CSDN通过智能技术生成

993. 二叉树的堂兄弟节点

在这里插入图片描述
BFS, 往往都需要根据问题自己定义一个数据结构 以后存入队列中,框架十分简单 取队列首部-do sth-弹出队首:就是while(q.length){ cur = q[0]; /*do sth*/ q.shift(); }

// https://leetcode-cn.com/problems/cousins-in-binary-tree/
const isCousins = function (root, x, y) {
    let dx = -1, dy = -1, px = null, py = null;
    let q = [];
    q.push({
        node: root,
        pNode: null,
        depth: 0,
    });
    while (q.length) {
        let cur = q[0];
            if (cur.node.val == x) {
                dx = cur.depth
                px = cur.pNode
            };
            if (cur.node.val == y) {
                dy = cur.depth
                py = cur.pNode
            };
            cur.node.left && q.push({
                node: cur.node.left, pNode: cur.node, depth: cur.depth + 1
            });
            cur.node.right && q.push({
                node: cur.node.right, pNode: cur.node, depth: cur.depth + 1
            });
        q.shift();
    }
    return dx == dy && px != py
};

其实JS语法特性可以让一些代码再简洁一些,看下题

剑指 Offer 13. 机器人的运动范围

在这里插入图片描述

const movingCount = function (m, n, k) {
    const calcSum = (x, y) => (x + '' + y).split('').reduce((acc, cur) => +cur + acc, 0)
    const dir = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    let vis = new Set(['0, 0']);
    let q = [[0, 0]];
    let res = 1;
    while (q.length) {
        let [i, j] = q.shift();
        for (let d of dir) {
            let x = i + d[0];
            let y = j + d[1];
            if (x < 0 || x >= m ||
                y < 0 || y >= n ||
                calcSum(x, y) > k ||
                vis.has(x + ', ' + y)) {
                continue;
            }
            res += 1;
            vis.add(x + ', ' + y);
            q.push([x, y]);
        }
    }
    return res;
};

5. 最长回文子串

在这里插入图片描述

// https://leetcode-cn.com/problems/longest-palindromic-substring/
const longestPalindrome = function (s) {
    if (s.length < 2) return s
    let res = '';
    for (let i = 0; i < s.length; i++) {
        expand(s, i, i);
        expand(s, i, i + 1);
    }
    function expand(s, i, j) {
        while (s[i] == s[j] && i >= 0 && j < s.length) {
            i--; j++;
        }
        j--; i++; // 注意,while里面多做了一次,要回退一下
        let len = j - i + 1
        if (len > res.length) res = s.slice(i, j + 1)
    }

    return res
};

56. 合并区间

在这里插入图片描述

// https://leetcode-cn.com/problems/merge-intervals/submissions/
const merge = (arr)=>{
    arr.sort((a,b)=>a[0] - b[0])
    let res = [arr[0]]
    for (let curr of arr){
        last = res[res.length - 1]
        if(curr[0] > last[1]){
            res.push(curr)
        } else {
            last[1] = Math.max(curr[1], last[1])
        }
    }
    return res
}

1846. Maximum Element After Decreasing and Rearranging

在这里插入图片描述
关注的是"数组元素的取值" 若存在断层 则要全部下沉 届时顶端元素即为所求最大元素;
因为要求相邻元素不差过1,因此调整后取值最大不超过n,如果全部下沉压缩 空取值元素 以及重复的那些取值元素 会使顶端元素远小于n,
那么我们要使重复取值元素 分散到空取值处 填补断层,使下沉尽量少发生 顶端元素接近于n;

// https://leetcode-cn.com/problems/maximum-element-after-decreasing-and-rearranging/
const maximumElementAfterDecrementingAndRearranging = function(arr) {
    const n = arr.length;
    let count = new Array(n + 1).fill(0);
    for(let num of arr){
        count[Math.min(num, n)]++; // 所有大于n的都当做是n进行计数
    }
    let miss = 0;
    for(let idx = 1; idx < n + 1; idx++) {
        if (count[idx] == 0) { miss++; }
        else if(count[idx] > 1) { // 可以分出一些元素填到miss的位置中
            miss -= Math.min(miss, count[idx] - 1); // 自己也要留1个,占位越多 最后得到的最大值越大 
        }
    }
    return n - miss;
};

23. 合并K个升序链表

在这里插入图片描述
对于JS,用上reduce这个题相当于简单题了,转为合并2个游戏链表

// https://leetcode-cn.com/problems/merge-k-sorted-lists/
const mergeKLists = function (lists) {
    if (!lists || !lists.length) { return null }
    return lists.reduce(merge2Lists)
};

const merge2Lists = (a, b) => {
    if (!a) return b;
    if (!b) return a;
    if (a.val < b.val) {
        a.next = merge2Lists(a.next, b)
        return a
    } else {
        b.next = merge2Lists(b.next, a)
        return b
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值