部分力扣题记

1.. - 力扣(LeetCode)

这题用到了map和栈的知识点

我们利用map的特性,将()【】{},分别一一对应

然后遍历,如果map(char)为真,就意味着是左边的部分(【{,将其入栈

然后如果map(char)不为真,意味着是右边的部分)】},我们就进行判断,如果map(char)=现在栈顶的元素stack.pop(),就返回真,不然报错

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    const stack=[];
    const map={'(':')','[':']','{':'}'};
    for(let i=0;i<s.length;i++){
        const char=s[i];
        if(map[char]){
            stack.push(char);
        }else{
            const top=stack.pop();
            if(map[top]!=char){
                return false
            }
            
        }

    }
    return stack.length===0;
};
const s='()[]{}'
console.log(isValid(s))

2.. - 力扣(LeetCode)

二叉树是一种树形数据结构,其中每个节点最多有两个子节点,通常称为"左子节点"和"右子节点"。

前序遍历是一种遍历二叉树的方式,其顺序如下:

  1. 访问根节点。
  2. 前序遍历左子树。
  3. 前序遍历右子树。

这个题首先你得手动构建一下二叉树结构,然后写一个方法将数组变为二叉树结构

最后用入栈和出栈实现

var TreeNode = /** @class */ (function () {
    function TreeNode(val, left, right) {
        if (val === void 0) { val = 0; }
        if (left === void 0) { left = null; }
        if (right === void 0) { right = null; }
        this.val = val;
        this.left = left;
        this.right = right;
    }
    return TreeNode;
}());
var buildTree = function (arr, index) {
    if (index === void 0) { index = 0; }
    if (index >= arr.length || arr[index] === null) {
        return null;
    }
    var node = new TreeNode(arr[index]);
    node.left = buildTree(arr, 2 * index + 1);
    node.right = buildTree(arr, 2 * index + 2);
    return node;
};
var preorderTraversal = function (root) {
    var res = [];
    if (!root)
        return res;
    var stack = [root];
    while (stack.length !== 0) {
        var node = stack.pop();
        if (node) {
            res.push(node.val);
            if (node.right) {
                stack.push(node.right);
            }
            if (node.left) {
                stack.push(node.left);
            }
        }
    }
    return res;
};
var rootArray = [1, null, 2, 3];
var root = buildTree(rootArray);
console.log(preorderTraversal(root)); // 输出: [1, 2, 3]

3.. - 力扣(LeetCode)

这个题很简单

  • this.queue.push(t):将当前请求的时间戳 t 添加到队列 queue 中。

  • while (this.queue[0] < t - 3000):当队列中最早的请求时间小于当前时间 t 减去 3000 毫秒时,将其从队列中移除。这一步保证了队列中只保留最近 3000 毫秒内的请求。

    var RecentCounter = function() {
    this.queue = [];
    };

    RecentCounter.prototype.ping = function(t) {
    this.queue.push(t);
    while (this.queue[0] < t - 3000) {
    this.queue.shift();
    }
    return this.queue.length;
    };

4.. - 力扣(LeetCode)

例如,给定链表 4→5→1→9,要被删除的节点是 5,即链表中的第 2 个节点。可以通过如下两步操作实现删除节点的操作。

将第 2 个节点的值修改为第 3 个节点的值,即将节点 5 的值修改为 1,此时链表如下:

4→1→1→9

删除第 3 个节点,此时链表如下:

4→1→9

var deleteNode = function(node) {
    node.val = node.next.val;
    node.next = node.next.next;
};

5.. - 力扣(LeetCode)

在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。

var reverseList = function(head) {
    let prev = null;
    let curr = head;
    while (curr) {
        const next = curr.next;
        curr.next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
};

6.. - 力扣(LeetCode)

这里要考虑是进位值

由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。

我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2,进位值为 carry,则它们的和为 n1+n2+carry;其中,答案链表处相应位置的数字为 (n1+n2+carry)mod10,而新的进位值为 ⌊

10

n1+n2+carry

如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0 。

此外,如果链表遍历结束后,有 carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry。

var addTwoNumbers = function(l1, l2) {
    let head = null, tail = null;
    let carry = 0;
    while (l1 || l2) {
        const n1 = l1 ? l1.val : 0;
        const n2 = l2 ? l2.val : 0;
        const sum = n1 + n2 + carry;
        if (!head) {
            head = tail = new ListNode(sum % 10);
        } else {
            tail.next = new ListNode(sum % 10);
            tail = tail.next;
        }
        carry = Math.floor(sum / 10);
        if (l1) {
            l1 = l1.next;
        }
        if (l2) {
            l2 = l2.next;
        }
    }
    if (carry > 0) {
        tail.next = new ListNode(carry);
    }
    return head;
};

7.跳转提示-稀土掘金

细节

当我们遍历到链表的最后一个节点时,cur.next 为空节点,如果不加以判断,访问 cur.next 对应的元素会产生运行错误。因此我们只需要遍历到链表的最后一个节点,而不需要遍历完整个链表。

var deleteDuplicates = function(head) {
    if (!head) {
        return head;
    }

    let cur = head;
    while (cur.next) {
        if (cur.val === cur.next.val) {
            cur.next = cur.next.next;
        } else {
            cur = cur.next;
        }
    }
    return head;
};

8.. - 力扣(LeetCode)

var hasCycle = function (head) {
    let slow = head, fast = head; // 乌龟和兔子同时从起点出发
    while (fast && fast.next) {
        slow = slow.next; // 乌龟走一步
        fast = fast.next.next; // 兔子走两步
        if (fast === slow) // 兔子追上乌龟(套圈),说明有环
            return true;
    }
    return false; // 访问到了链表末尾,无环
};

9.. - 力扣(LeetCode)

hash的办法

哈希集合(HashSet)是一种基于哈希表的数据结构,主要用于存储不重复的元素。它允许以常数时间复杂度(O(1))进行添加、删除和查找操作。JavaScript 中没有直接的 HashSet 实现,但我们可以使用 Set 对象来实现类似的功能。

function intersection(nums1, nums2) {
    let result = [];
    let hash = {};

    // 填充哈希表
    for (const num of nums1) {
        hash[num] = 1;
    }

    // 查找交集并更新结果
    for (const num of nums2) {
        if (hash[num]) {
            result.push(num);
            hash[num] = 0; // 确保每个元素只添加一次
        }
    }

    return result;
}

// 测试用例
const nums1 = [1, 2, 2, 1];
const nums2 = [2, 2];
console.log(intersection(nums1, nums2)); // 输出: [2]

const nums3 = [4, 9, 5];
const nums4 = [9, 4, 9, 8, 4];
console.log(intersection(nums3, nums4)); // 输出: [4, 9]
相关推荐
ALISHENGYA10 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo11 分钟前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc18 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
姚先生9729 分钟前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵
测试杂货铺1 小时前
如何用postman做接口自动化测试及完美的可视化报告?
自动化测试·软件测试·测试工具·职场和发展·jenkins·压力测试·postman
游是水里的游1 小时前
【算法day20】回溯:子集与全排列问题
算法
yoyobravery1 小时前
c语言大一期末复习
c语言·开发语言·算法
Jiude2 小时前
算法题题解记录——双变量问题的 “枚举右,维护左”
python·算法·面试
被AI抢饭碗的人2 小时前
算法题(13):异或变换
算法
nuyoah♂3 小时前
DAY36|动态规划Part04|LeetCode:1049. 最后一块石头的重量 II、494. 目标和、474.一和零
算法·leetcode·动态规划