TypeScript算法题实战——剑指 Offer篇(4)

news2024/12/25 9:13:18

目录

  • 一、礼物的最大价值
    • 1.1、题目描述
    • 1.2、题解
  • 二、最长不含重复字符的子字符串
    • 2.1、题目描述
    • 2.2、题解
  • 三、丑数
    • 3.1、题目描述
    • 3.2、题解
  • 四、第一个只出现一次的字符
    • 4.1、题目描述
    • 4.2、题解
  • 五、数组中的逆序对
    • 5.1、题目描述
    • 5.2、题解
  • 六、两个链表的第一个公共节点
    • 6.1、题目描述
    • 6.2、题解
  • 七、在排序数组中查找数字 I
    • 7.1、题目描述
    • 7.2、题解
  • 八、0~n-1中缺失的数字
    • 8.1、题目描述
    • 8.2、题解
  • 九、二叉搜索树的第k大节点
    • 9.1、题目描述
    • 9.2、题解
  • 十、二叉树的深度
    • 10.1、题目描述
    • 10.2、题解
  • 最后

随着TypeScript的流行,越来越多的开发者开始使用TypeScript来解决算法问题。

在本文中,我们将使用TypeScript来解决剑指offer的算法题。这些问题涵盖了各种各样的主题,包括数组、字符串、链表、树、排序和搜索等。我们将使用TypeScript的强类型和面向对象的特性来解决这些问题,并通过实际的代码示例来演示如何使用TypeScript来解决算法问题。

题目全部来源于力扣题库:《剑指 Offer(第 2 版)》本章节包括的题目有:

题目难度
礼物的最大价值简单
最长不含重复字符的子字符串简单
丑数中等
第一个只出现一次的字符简单
数组中的逆序对困难
两个链表的第一个公共节点简单
在排序数组中查找数字 I中等
0~n-1中缺失的数字简单
二叉搜索树的第k大节点简单
二叉树的深度简单

一、礼物的最大价值

1.1、题目描述

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

1.2、题解

使用动态规划方法,原地更改grid数组,更改后的grid数组中,grid[i][j]表示当前走到第i行第j列作为终点最多可以获得的价值

可以得知第一行的数只可从左边到达,如grid[0][3],只可能是从grid[0][0]、grid[0][1]、grid[0][2]依次走过来,不可能有其他方案,故grid[0][3]时最多获取的价值只有grid[0][0]+grid[0][1]+grid[0][2]+grid[0][3]

同理得知第一列的数只可从上边到达。如此即可初始化所有 grid[i][0]grid[0][j]的状态

非第一行和第一列的状态方程为grid[i][j] = Math.max(grid[i][j - 1], grid[i - 1][j]) + grid[i][j];,即选择左边和上边的较大的价值,与自身相加,即为到自身处时能够获取的最大价值:

function maxValue(grid: number[][]): number {
    const m:number = grid.length;
    const n:number = grid[0].length;
    for(let i = 1 ; i < m; i++){
        grid[i][0] = grid[i][0] + grid[i - 1][0];
    }
    for(let j = 1; j < n; j++){
        grid[0][j] = grid[0][j] + grid[0][j - 1];
    }

    for(let i = 1; i < m; i++){
        for(let j = 1; j < n; j++){
            grid[i][j] = Math.max(grid[i][j - 1], grid[i - 1][j]) + grid[i][j];
        }
    }
    return grid[m - 1][n - 1];
};

二、最长不含重复字符的子字符串

2.1、题目描述

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例 1: 输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3: 输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

2.2、题解

方法一:队列+哈希表
使用队列,挨个存数字,如遇到重复,则从队首弹出元素直至弹出到不重复为止(使用哈希表来判断重复)

function lengthOfLongestSubstring(s: string): number {
    let myQue:string[] = [];
    let storeSet: Set<string> = new Set();
    let maxLength: number = 0;
    for(let i = 0; i < s.length; i++){
        if(!storeSet.has(s[i]))
            storeSet.add(s[i]);
        else{
            while(1){
                let tmpStr = myQue.shift();
                if(tmpStr == s[i])
                    break;
                storeSet.delete(tmpStr);
            }
        }
        myQue.push(s[i]);
        
        if(myQue.length> maxLength)
            maxLength = myQue.length;  
    }
    return maxLength;
};

方法二:动态规划+哈希map

遍历字符串,使用哈希map统计各个字符最后一次出现时的索引位置

使用动态规划,dp[j]表示以s[j]为结尾的“最长不重复子字符串”长度,设s[i]为与s[j]相同的上一个重复字符;

状态转移方程可以列为:

  1. 当i<0时,即没有找到,dp[j] = dp[j-1] + 1;
  2. 当dp[j - 1] < j - i,说明字符s[i]在子字符串dp[j - 1] 区间之外,也就是dp[j - 1]的状态不会影响本次计算,即dp[j] = dp[j - 1] + 1
  3. 当dp[j - 1] >= j - i,说明字符s[i]在子字符串dp[j - 1] 区间之内,也就是dp[j - 1]的状态会影响本次计算,他包含了本字符,强行加进来会导致字符重复,故dp[j] = j - i;

时间复杂度为O(N)空间复杂度为O(1)

function lengthOfLongestSubstring(s: string): number {
    let myMap: Map<string, number> = new Map();
    let maxLength:number = 0;
    let tmp = 0;
    let j = -1
    for(let i = 0; i < s.length; i++){
        if(myMap.has(s[i])){
           j = myMap.get(s[i]);
        }
        myMap.set(s[i], i);
        tmp = tmp < i - j ? (tmp + 1) : (i - j);
        if(tmp > maxLength)
            maxLength = tmp;
    }
    return maxLength;
};

三、丑数

3.1、题目描述

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

3.2、题解

除了dp[0] = 1,所有丑数均是前面的丑数乘以2或者3或者5得到的,由此性质来做动态规划:

  1. 将前面求得的丑数记录下来,后面的丑数就是前面的某个丑数*2,*3,*5
  2. 但是问题来了,我怎么确定已知前面k-1个丑数,我怎么确定第k个丑数呢
  3. 采取用三个指针的方法,p2,p3,p5
  4. index2指向的数字number2下一次永远*2index2指向的数字number3下一次永远*3index2指向的数字number5永远*5
  5. 我们从2*number2 3*number3 5*number5选取最小的一个数字,作为第k个丑数
  6. 如果第K个丑数==2*number2,也就是说前面0-index2个丑数*2不可能产生比第K个丑数更大的丑数了,所以index2++
  7. index3,index5同理
  8. 返回第n个丑数
function nthUglyNumber(n: number): number {
    let dp: number[] = [1];
    let [index2, index3, index5] = [0, 0, 0];
    let number2: number, number3:number, number5:number;
    for(let i = 1; i < n; i++){
        number2 = 2 * dp[index2];
        number3 = 3 * dp[index3];
        number5 = 5 * dp[index5];
        dp[i] = Math.min(number2, number3, number5);
        console.log(index2,index3,index5);
        if(dp[i] == number2) index2++;
        if(dp[i] == number3) index3++;
        if(dp[i] == number5) index5++;
    }
    return dp[n - 1];
};

四、第一个只出现一次的字符

4.1、题目描述

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例 1:
输入:s = “abaccdeff”
输出:‘b’

示例 2:
输入:s = “”
输出:’ ’

4.2、题解

使用哈希map存储数字出现的频次,遍历第二遍时找到第一个频次为1的字符

function firstUniqChar(s: string): string {
    let storeMap:Map<string, number> = new Map();
    for(let i = 0; i < s.length; i++){
        if(storeMap.has(s[i])){
            storeMap.set(s[i], storeMap.get(s[i] + 1));
        }
        else
            storeMap.set(s[i], 1);
    }
     for(let i = 0; i < s.length; i++){
        if(storeMap.get(s[i]) == 1)
            return s[i];
    }
    return ' ';
};

五、数组中的逆序对

5.1、题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

示例 1:

输入: [7,5,6,4] 输出: 5

解释:75,76,74,54,64

5.2、题解

使用归并排序来做,每次在右指针移动时计算贡献度,贡献度为左数组里左指针以后的元素个数(leftLength - i)。

如7,5,6,4,归并排序首先将其转成[7],[5],[6],[4]这四个小数组,然后分析[7]和[5],7比5大,归并排序后为[5,7],7对于逆序的贡献为1,分析[6]和[4],6比4大,归并排序后为[4,6],6对于逆序的贡献为1,

然后再分析[5,7]和[4,6],排序的过程如下:首先变为[4,],无贡献,然后变为[4,5],5对于逆序的贡献为2 - 0 = 2,然后变为[4,5,6],6对于逆序的贡献度为2 - 1 =1,最后变为[4,5,6,7],贡献度总和为5。

function reversePairs(nums: number[]): number {
    let cal = 0;
    mergeSort(nums);
    return cal;

    function mergeSort(arr: number[]): number[] {
        if(arr.length < 2){
            return arr;
        }
        let mid = Math.floor(arr.length/2);
        let left = arr.slice(0, mid);
        let right = arr.slice(mid);

        return merge(mergeSort(left), mergeSort(right));
    }
    function merge(left:number[], right:number[]):number[]{
        let res = [];
        let leftLength = left.length;
        let rightLength = right.length;
        let len = leftLength + rightLength;
        for(let index = 0, i = 0, j = 0; index < len; index++){
            // 左数组已经遍历完
            if(i >= leftLength){
                res[index] = right[j++];
            }
            // 右数组已经遍历完
            else if(j >= rightLength){
                res[index] = left[i++];
            }
            // 左数组当前指针指向的元素正常小于或者等于右数组当前指针指向的元素
            else if(left[i] <= right[j]){
                res[index] = left[i++];
            }
            // 左数组当前指针指向的元素大于右数组当前指针指向的元素
            else{
                res[index] = right[j++];
                cal += leftLength - i;
            }
        }
        return res;
    }
};

六、两个链表的第一个公共节点

6.1、题目描述

输入两个链表,找出它们的第一个公共节点。如:

这里是引用
在这里插入图片描述
在这里插入图片描述

6.2、题解

很经典的一道题目,可以使用哈希表法,先遍历一遍A链表,将结点存入哈希表当中,然后再遍历B链表,如果哈希表中存在该结点,则该结点就是第一个公共节点。

也可以使用双指针的解法,让A和B两个指针遍历一次自己的赛道后,交换赛道再跑一次即可,判断是否相交。

var getIntersectionNode = function(headA, headB) {
    if(headA === null || headB === null)
        return null;
    let pA = headA, pB = headB;
    while(pA != pB){
        if(pA != null){
            pA = pA.next; 
        }else{
            pA = headB;
        }
        if(pB != null){
            pB = pB.next;
        }else{
            pB = headA;
        }
    }
    return pA;
};

七、在排序数组中查找数字 I

7.1、题目描述

统计一个数字在排序数组中出现的次数。

示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2

示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

7.2、题解

使用两次二分法,先找到第一次出现target的数,再找到最后一次出现target的数,然后两者下标相减+1,即为等于target的数的个数。

function search(nums: number[], target: number): number {
    let left = 0;
    let right = nums.length - 1;
    let first = -1;
    let last = -1;
    while(left <= right){
        let middle = left + right >> 1;
        if(nums[middle] == target){
            first = middle;
            right = middle - 1;  // 核心
        }else if(nums[middle] > target){
            right = middle - 1;
        }
        else{
            left = middle + 1;
        }
    }
    left = 0, right = nums.length - 1;
    while(left <= right){
        let middle = left + right >> 1;
        if(nums[middle] == target){
            last = middle;
            left = middle + 1;  // 核心
        }else if(nums[middle] > target){
            right = middle - 1;
        }
        else{
            left = middle + 1;
        }
    }
    if(first == -1)
        return 0;
    else
        return last - first + 1;
};

八、0~n-1中缺失的数字

8.1、题目描述

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

示例 1:
输入: [0,1,3]
输出: 2

示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8

8.2、题解

同样使用二分法,由于题目是一个从0到n-1的长度为n-1的递增排序数组,所以只需要判断nums[middle] == middle如果为True,说明左边的那一半没有问题,再看右边的这一半,如果为False,说明左边这一半有问题,看左边这一半。

function missingNumber(nums: number[]): number {
    let left = 0;
    let right = nums.length - 1;
    let middle = 0;
    while(left <= right){
        middle = left + right >> 1;
        if(nums[middle] == middle){
            left = middle + 1;
        }
        else{
            right = middle - 1;
        }
    }
    // console.log(left, middle, right);
    return left;
};

九、二叉搜索树的第k大节点

9.1、题目描述

给定一棵二叉搜索树,请找出其中第 k 大的节点的值。

这里是引用

9.2、题解

这题利用二叉搜索树的性质,二叉搜索树的先序遍历即为从小到大的排序,那么要求第k大节点,即可以先先序遍历,然后输出倒数第k个结点(valArray.length - k)即可。

function kthLargest(root: TreeNode | null, k: number): number {
    let valArray: number[] = [];
    function traverse(root: TreeNode, valArray:number[]){
        if(root == null)
            return;
        traverse(root.left,valArray);
        valArray.push(root.val);
        traverse(root.right,valArray);
    }
    traverse(root, valArray);
    return valArray[valArray.length - k];
};

十、二叉树的深度

10.1、题目描述

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

例如:
在这里插入图片描述

给定二叉树 [3,9,20,null,null,15,7],返回它的最大深度 3 。

10.2、题解

第一种方法,直接递归判断,当前树的最大深度= 1 + max(左子树的深度,右子树的深度)

function maxDepth(root: TreeNode | null): number {
    if(root == null)
        return 0;
    return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
};

第二种方法,层序遍历算总层数即可,关于层序遍历可以看:TypeScript算法题实战——二叉树篇

function maxDepth(root: TreeNode | null): number {
    let res: number[][] = [];
    let tmpList: TreeNode[] = [];
    if(root !== null)
        tmpList.push(root);
    while(tmpList.length > 0){
        let tmpArray:number[] = [];
        for(let i = 0, length = tmpList.length; i < length; i++){
            let tmpNode: TreeNode = tmpList.shift();
            tmpArray.push(tmpNode.val);
            if(tmpNode.left)
                tmpList.push(tmpNode.left);
            if(tmpNode.right)
                tmpList.push(tmpNode.right);
        }
        res.push(tmpArray);
    }
    // console.log(res);
    return res.length;
 };

最后

💖 个人简介:人工智能领域研究生,目前主攻文本生成图像(text to image)方向

📝 关注我:中杯可乐多加冰

🔥 限时免费订阅:TypeScript实战

📝 加入社群 抱团学习:中杯可乐的答疑交流群

🎉 支持我:点赞👍+收藏⭐️+留言📝

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/745854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

任务型对话对话策略学习的强化学习方法

任务型对话(TOD)系统旨在帮助用户解决从天气咨询到计划安排的一系列问题。完成任务的途径有二。 其一是端到端途径&#xff1a;直接将当前对话内容与系统的自然语言反映相关联。此种方法多是采用序列到序列的模型&#xff0c;然后进行监督训练。 第二种是模组途径&#xff1a…

can 相关背题

1 CAN FD 和CAN的 区别&#xff1a; CAN-FD&#xff1a;一帧数据最长64字节。以理解成CAN协议的升级版&#xff0c;只升级了协议&#xff0c;物理层未改变。传输速率不同、数据长度不同、帧格式不同、ID长度不同。 1&#xff09;速率不同&#xff1a; CAN&#xff1a;最大传…

机械臂的雅克比矩阵推导

1. 线速度和角速度的递推通式推导 p i p i − 1 R i − 1 r i − 1 , i i − 1 \mathbf{p}_{i}\mathbf{p}_{i-1}\mathbf{R}_{i-1} \mathbf{r}_{i-1, i}^{i-1} pi​pi−1​Ri−1​ri−1,ii−1​ p i − 1 \mathbf{p}_{i-1} pi−1​是 { i − 1 } \{i-1\} {i−1}坐标系的原点的…

获取全国各地行政区的genjson数据以及使用leaflet加载行政区数据

前言 在写代码之前&#xff0c;我们需要做一些准备工作&#xff0c;需要有一份某个行政区的geojson数据&#xff0c;如果你没有也没关系&#xff0c;我们可以去下载&#xff0c;地址&#xff1a;geojson数据下载网站 打开网站&#xff0c;选择自己想要获取的行政区&#xff0…

FPGA学习——按键控制LED流水灯(附源码 无按键消抖版本)

文章目录 一、前言二、开发板按键原理图三、源码四、实现效果 一、前言 在博主的cyclone4开发板上一共有4个按键&#xff0c;本次实验的目的是为了实现每按下一次按键&#xff0c;都会使开发板上的4个LED灯切换一次状态&#xff0c;博主一共设计了四种状态&#xff0c;分别是&…

滴水逆向三期笔记与作业——02C语言——04 IF语句逆向分析下

OneNote防丢失。 海哥牛逼。 目录 一、if…else...反汇编1、反汇编特点2、案例分析 二、作业1三、IF...ELSE IF...ELSE IF..多分支语句1、多分支反汇编2、案例分析 四、作业2 一、if…else…反汇编 1、反汇编特点 2、案例分析 二、作业1 解&#xff1a; 分析图&#xff1a; 分…

【基于矢量射线的衍射积分 (VRBDI)】基于矢量射线的衍射积分 (VRBDI) 和仿真工具(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

前端开发中常见的20个数组方法,你掌握了几个?

文章目录 前言一、常见的数组方法1.1 push (将指定的元素添加到数组的末尾&#xff0c;并返回新的数组长度)1.2 pop (从数组中删除最后一个元素&#xff0c;并返回该元素的值)1.3 shift (从数组中删除第一个元素&#xff0c;并返回该元素的值)1.4 unshift (向数组首位添加一个或…

路径规划算法:基于鹈鹕优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于鹈鹕优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于鹈鹕优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法鹈鹕…

VirtualBox单机版安装K8S+TF

本文参考自&#xff1a;kubernetes最新版安装单机版v1.21.5_kubernetes下载_qq759035366的博客-CSDN博客 只用一台VB虚拟机&#xff0c;装K8S加Tungsten Fabric。 0. 提前避坑&#xff1a; 0.1 Tungsten Fabric的VRouter对Linux内核版本有要求&#xff0c;以下内核版本才…

音视频——码率、帧率越高越清晰?分辨率、像素、dpi的关系

一 前言 本期我介绍一下视频的一些基础概念&#xff0c;如帧率、码率、分辨率、像素、dpi、视频帧、I帧、P帧、gop等。我i初步学习音视频&#xff0c;给这些专业词汇进行扫盲 会解释多少码率是清晰的&#xff0c;是否帧率越高越流畅等问题。 这些概念是比较杂乱的&#xff0c…

微信二维码登录,修改下面提示的字体和样式

背景 由于业务需要&#xff0c;需要把微信二维码下面默认的提示文字进行修改&#xff0c;如下图所示&#xff1a; 需要修改上面红色框内选择的字体&#xff0c;在研究的过程中&#xff0c;发现好多人都在查询这个问题&#xff0c;并且有些网友思路也是对的。可能只是方式没对。…

库存扣减设计和下单

这里写目录标题 前言正文库存设计原则常见库存扣减方案秒杀订单域设计整体服务领域模型领域服务领域事件之下单下单整体流程同步下单库存预扣减库存扣减 总结参考链接 前言 大家好&#xff0c;我是练习两年半的Java练习生&#xff0c;前面我们已经介绍了领域驱动和缓存设计&am…

路径规划算法:基于金豺优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于金豺优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于金豺优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法金豺…

【网络编程】应用层协议——HTTPS协议(数据的加密与解密)

文章目录 一、HTTP协议的缺陷二、HTTPS协议的介绍三、加密与解密3.1 加密与解密流程3.2 为什么要加密和解密3.3 常见的加密方式3.3.1 对称加密3.3.2 非对称加密3.3.3 数据摘要&#xff08;数据指纹&#xff09;3.3.4 数据签名 四、HTTPS工作过程4.1 中间人攻击方式4.2 数字证书…

50行PyTorch代码中的生成对抗网络(GAN)

一、说明 2014年,蒙特利尔大学的伊恩古德费罗(Ian Goodfellow)和他的同事发表了一篇令人惊叹的论文,向世界介绍了GANs或生成对抗网络。通过计算图和博弈论的创新组合,他们表明,如果有足够的建模能力,相互竞争的两个模型将能够通过普通的旧反向传播进行共同训练。 二、原…

大学啥也没有学到,跑到培训班里学技术,真的有用吗-以下来自一位认识的朋友投稿-王大师

在学习IT技术的过程中&#xff0c;你是否也被安利过各种五花八门的技术培训班&#xff1f;这些培训班都是怎样向你宣传的&#xff0c;你又对此抱有着怎样的态度呢&#xff1f;在培训班里学技术&#xff0c;真的有用吗&#xff1f;–王大师告诉你 1、掌握 JAVA入门到进阶知识(持…

极验滑块(3代)验证码细节避坑总结

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 关于 w 值…

惊!这道题正确率竟然只有 22%:答案详解

《Go 语言爱好者周刊》第 148 期有一道题目&#xff1a;以下代码输出什么&#xff1f; package mainimport ("fmt" )func main() {m : [...]int{a: 1,b: 2,c: 3,}m[a] 3fmt.Println(len(m)) }A&#xff1a;3&#xff1b;B&#xff1a;4&#xff1b;C&#xff1a;10…

面试官:过滤器和拦截器有什么区别?

过滤器&#xff08;Filter&#xff09;和拦截器&#xff08;Interceptor&#xff09;都是基于 AOP&#xff08;Aspect Oriented Programming&#xff0c;面向切面编程&#xff09;思想实现的&#xff0c;用来解决项目中某一类问题的两种“工具”&#xff0c;但二者有着明显的差…