JavaScript刷LeetCode模板技巧篇(一)

news2024/12/23 17:31:27

虽然很多人都觉得前端算法弱,但其实 JavaScript 也可以刷题啊!最近两个月断断续续刷完了 leetcode 前 200 的 middle + hard ,总结了一些刷题常用的模板代码。

常用函数

包括打印函数和一些数学函数。

const _max = Math.max.bind(Math);
const _min = Math.min.bind(Math);
const _pow = Math.pow.bind(Math);
const _floor = Math.floor.bind(Math);
const _round = Math.round.bind(Math);
const _ceil = Math.ceil.bind(Math);
const log = console.log.bind(console);
//const log = _ => {}

log 在提交的代码中当然是用不到的,不过在调试时十分有用。但是当代码里面加了很多 log 的时候,提交时还需要一个个注释掉就相当麻烦了,只要将log赋值为空函数就可以了。

举一个简单的例子,下面的代码是可以直接提交的。

// 计算 1+2+...+n
// const log = console.log.bind(console);
const log = _ => {}

function sumOneToN(n) {
    let sum = 0;
    for (let i = 1; i <= n; i++) {
        sum += i;
        log(`i=${i}: sum=${sum}`);
    }
    return sum;
}

sumOneToN(10);

位运算的一些小技巧

判断一个整数 x 的奇偶性:x & 1 = 1 (奇数) , x & 1 = 0 (偶数)

求一个浮点数 x 的整数部分:~~x,对于正数相当于 floor(x) 对于负数相当于 ceil(-x)

计算 2 ^ n1 << n 相当于 pow(2, n)

计算一个数 x 除以 2 的 n 倍:x >> n 相当于 ~~(x / pow(2, n))

判断一个数 x 是 2 的整数幂(即 x = 2 ^ n): x & (x - 1) = 0

※注意※:上面的位运算只对32位带符号的整数有效,如果使用的话,一定要注意数!据!范!围!

记住这些技巧的作用:

提升运行速度 ❌

提升逼格 ✅

举一个实用的例子,快速幂(原理自行google)

// 计算x^n n为整数
function qPow(x, n) {
    let result = 1;
    while (n) {
        if (n & 1) result *= x; // 同 if(n%2)
        x = x * x;
        n >>= 1; // 同 n=floor(n/2)
    }
    return result;
}

链表

刚开始做 LeetCode 的题就遇到了很多链表的题。恶心心。最麻烦的不是写题,是调试啊!!于是总结了一些链表的辅助函数。

/** * 链表节点 * @param {*} val
 * @param {ListNode} next
 */
function ListNode(val, next = null) {
    this.val = val;
    this.next = next;
}
/** * 将一个数组转为链表 * @param {array} a
 * @return {ListNode} */
const getListFromArray = (a) => {
    let dummy = new ListNode()
    let pre = dummy;
    a.forEach(x => pre = pre.next = new ListNode(x));
    return dummy.next;
}
/** * 将一个链表转为数组 * @param {ListNode} node
 * @return {array} */
const getArrayFromList = (node) => {
    let a = [];
    while (node) {
        a.push(node.val);
        node = node.next;
    }
    return a;
}
/** * 打印一个链表 * @param {ListNode} node  */
const logList = (node) => {
    let str = 'list: ';
    while (node) {
        str += node.val + '->';
        node = node.next;
    }
    str += 'end';
    log(str);
}

还有一个常用小技巧,每次写链表的操作,都要注意判断表头,如果创建一个空表头来进行操作会方便很多。

let dummy = new ListNode();
// 返回
return dummy.next;

使用起来超爽哒~举个例子。@leetcode 82。题意就是删除链表中连续相同值的节点。

/** * @param {ListNode} head
 * @return {ListNode} */
var deleteDuplicates = function(head) {
    // 空指针或者只有一个节点不需要处理
    if (head === null || head.next === null) return head;

    let dummy = new ListNode();
    let oldLinkCurrent = head;
    let newLinkCurrent = dummy;

    while (oldLinkCurrent) {
        let next = oldLinkCurrent.next;
        // 如果当前节点和下一个节点的值相同 就要一直向前直到出现不同的值
        if (next && oldLinkCurrent.val === next.val) {
            while (next && oldLinkCurrent.val === next.val) {
                next = next.next;
            }
            oldLinkCurrent = next;
        } else {
            newLinkCurrent = newLinkCurrent.next = oldLinkCurrent;
            oldLinkCurrent = oldLinkCurrent.next;
        }
    }
    newLinkCurrent.next = null; // 记得结尾置空~
    logList(dummy.next);
    return dummy.next;
};

deleteDuplicates(getListFromArray([1,2,3,3,4,4,5]));
deleteDuplicates(getListFromArray([1,1,2,2,3,3,4,4,5]));
deleteDuplicates(getListFromArray([1,1]));
deleteDuplicates(getListFromArray([1,2,2,3,3]));

参考视频:传送门

本地运行结果

list: 1->2->5->end
list: 5->end
list: end
list: 1->end

是不是很方便!

矩阵(二维数组)

矩阵的题目也有很多,基本每一个需要用到二维数组的题,都涉及到初始化,求行数列数,遍历的代码。于是简单提取出来几个函数。

/**
 * 初始化一个二维数组
 * @param {number} r 行数
 * @param {number} c 列数
 * @param {*} init 初始值
 */
const initMatrix = (r, c, init = 0) => new Array(r).fill().map(_ => new Array(c).fill(init));
/**
 * 获取一个二维数组的行数和列数
 * @param {any[][]} matrix
 * @return [row, col]
 */
const getMatrixRowAndCol = (matrix) => matrix.length === 0 ? [0, 0] : [matrix.length, matrix[0].length];
/**
 * 遍历一个二维数组
 * @param {any[][]} matrix 
 * @param {Function} func 
 */
const matrixFor = (matrix, func) => {
    matrix.forEach((row, i) => {
        row.forEach((item, j) => {
            func(item, i, j, row, matrix);
        });
    })
}
/**
 * 获取矩阵第index个元素 从0开始
 * @param {any[][]} matrix 
 * @param {number} index 
 */
function getMatrix(matrix, index) {
    let col = matrix[0].length;
    let i = ~~(index / col);
    let j = index - i * col;
    return matrix[i][j];
}
/**
 * 设置矩阵第index个元素 从0开始
 * @param {any[][]} matrix 
 * @param {number} index 
 */
function setMatrix(matrix, index, value) {
    let col = matrix[0].length;
    let i = ~~(index / col);
    let j = index - i * col;
    return matrix[i][j] = value;
}

找一个简单的矩阵的题示范一下用法。@leetcode 566。题意就是将一个矩阵重新排列为r行c列。

/** * @param {number[][]} nums
 * @param {number} r
 * @param {number} c
 * @return {number[][]} */
var matrixReshape = function(nums, r, c) {
    // 将一个矩阵重新排列为r行c列
    // 首先获取原来的行数和列数
    let [r1, c1] = getMatrixRowAndCol(nums);
    log(r1, c1);
    // 不合法的话就返回原矩阵
    if (!r1 || r1 * c1 !== r * c) return nums;
    // 初始化新矩阵
    let matrix = initMatrix(r, c);
    // 遍历原矩阵生成新矩阵
    matrixFor(nums, (val, i, j) => {
        let index = i * c1 + j; // 计算是第几个元素
        log(index);
        setMatrix(matrix, index, val); // 在新矩阵的对应位置赋值
    });
    return matrix;
};

let x = matrixReshape([[1],[2],[3],[4]], 2, 2);
log(x)

二叉树

当我做到二叉树相关的题目,我发现,我错怪链表了,呜呜呜这个更恶心。

当然对于二叉树,只要你掌握先序遍历,后序遍历,中序遍历,层序遍历,递归以及非递归版,先序中序求二叉树,先序后序求二叉树,基本就能AC大部分二叉树的题目了(我瞎说的)。

二叉树的题目 input 一般都是层序遍历的数组,所以写了层序遍历数组和二叉树的转换,方便调试。

function TreeNode(val, left = null, right = null) {
    this.val = val;
    this.left = left;
    this.right = right;
}
/**
 * 通过一个层次遍历的数组生成一棵二叉树
 * @param {any[]} array
 * @return {TreeNode}
 */
function getTreeFromLayerOrderArray(array) {
    let n = array.length;
    if (!n) return null;
    let index = 0;
    let root = new TreeNode(array[index++]);
    let queue = [root];
    while(index < n) {
        let top = queue.shift();
        let v = array[index++];
        top.left = v == null ? null : new TreeNode(v);
        if (index < n) {
            let v = array[index++];
            top.right = v == null ? null : new TreeNode(v);
        }
        if (top.left) queue.push(top.left);
        if (top.right) queue.push(top.right);
    }
    return root;
}
/**
 * 层序遍历一棵二叉树 生成一个数组
 * @param {TreeNode} root 
 * @return {any[]}
 */
function getLayerOrderArrayFromTree(root) {
    let res = [];
    let que = [root];
    while (que.length) {
        let len = que.length;
        for (let i = 0; i < len; i++) {
            let cur = que.shift();
            if (cur) {
                res.push(cur.val);
                que.push(cur.left, cur.right);
            } else {
                res.push(null);
            }
        }
    }
    while (res.length > 1 && res[res.length - 1] == null) res.pop(); // 删掉结尾的 null
    return res;
}

一个例子,@leetcode 110,判断一棵二叉树是不是平衡二叉树。

/** * @param {TreeNode} root * @return {boolean} */
var isBalanced = function(root) {
    if (!root) return true; // 认为空指针也是平衡树吧

    // 获取一个二叉树的深度
    const d = (root) => {
        if (!root) return 0;
        return _max(d(root.left), d(root.right)) + 1;
    }

    let leftDepth = d(root.left);
    let rightDepth = d(root.right);

    // 深度差不超过 1 且子树都是平衡树
    if (_min(leftDepth, rightDepth) + 1 >= _max(leftDepth, rightDepth)
        && isBalanced(root.left) && isBalanced(root.right)) return true;

    return false;
};

log(isBalanced(getTreeFromLayerOrderArray([3,9,20,null,null,15,7])));
log(isBalanced(getTreeFromLayerOrderArray([1,2,2,3,3,null,null,4,4])));

二分查找

参考 C++ STL 中的 lower_boundupper_bound。这两个函数真的很好用的!

/** * 寻找>=target的最小下标 * @param {number[]} nums
 * @param {number} target
 * @return {number} */
function lower_bound(nums, target) {
    let first = 0;
    let len = nums.length;

    while (len > 0) {
        let half = len >> 1;
        let middle = first + half;
        if (nums[middle] < target) {
            first = middle + 1;
            len = len - half - 1;
        } else {
            len = half;
        }
    }
    return first;
}

/** * 寻找>target的最小下标 * @param {number[]} nums
 * @param {number} target
 * @return {number} */
function upper_bound(nums, target) {
    let first = 0;
    let len = nums.length;

    while (len > 0) {
        let half = len >> 1;
        let middle = first + half;
        if (nums[middle] > target) {
            len = half;
        } else {
            first = middle + 1;
            len = len - half - 1;
        }
    }
    return first;
}

照例,举个例子,@leetcode 34。题意是给一个排好序的数组和一个目标数字,求数组中等于目标数字的元素最小下标和最大下标。不存在就返回 -1。

/** * @param {number[]} nums
 * @param {number} target
 * @return {number[]} */
var searchRange = function(nums, target) {
  let lower = lower_bound(nums, target);
  let upper = upper_bound(nums, target);
  let size = nums.length;
  // 不存在返回 [-1, -1]
  if (lower >= size || nums[lower] !== target) return [-1, -1];
  return [lower, upper - 1];
};

在 VS Code 中刷 LeetCode

前面说的那些模板,难道每一次打开新的一道题都要复制一遍么?当然不用啦。

首先配置代码片段 选择 Code -> Preferences -> User Snippets ,然后选择 JavaScript

在这里插入图片描述

然后把文件替换为下面的代码:

{
  "leetcode template": {
    "prefix": "@lc",
    "body": [
      "const _max = Math.max.bind(Math);","const _min = Math.min.bind(Math);","const _pow = Math.pow.bind(Math);","const _floor = Math.floor.bind(Math);","const _round = Math.round.bind(Math);","const _ceil = Math.ceil.bind(Math);","const log = console.log.bind(console);","// const log = _ => {}","/**************** 链表 ****************/","/**"," * 链表节点"," * @param {*} val"," * @param {ListNode} next"," */","function ListNode(val, next = null) {","    this.val = val;","    this.next = next;","}","/**"," * 将一个数组转为链表"," * @param {array} array"," * @return {ListNode}"," */","const getListFromArray = (array) => {","    let dummy = new ListNode()","    let pre = dummy;","    array.forEach(x => pre = pre.next = new ListNode(x));","    return dummy.next;","}","/**"," * 将一个链表转为数组"," * @param {ListNode} list"," * @return {array}"," */","const getArrayFromList = (list) => {","    let a = [];","    while (list) {","        a.push(list.val);","        list = list.next;","    }","    return a;","}","/**"," * 打印一个链表"," * @param {ListNode} list "," */","const logList = (list) => {","    let str = 'list: ';","    while (list) {","        str += list.val + '->';","        list = list.next;","    }","    str += 'end';","    log(str);","}","/**************** 矩阵(二维数组) ****************/","/**"," * 初始化一个二维数组"," * @param {number} r 行数"," * @param {number} c 列数"," * @param {*} init 初始值"," */","const initMatrix = (r, c, init = 0) => new Array(r).fill().map(_ => new Array(c).fill(init));","/**"," * 获取一个二维数组的行数和列数"," * @param {any[][]} matrix"," * @return [row, col]"," */","const getMatrixRowAndCol = (matrix) => matrix.length === 0 ? [0, 0] : [matrix.length, matrix[0].length];","/**"," * 遍历一个二维数组"," * @param {any[][]} matrix "," * @param {Function} func "," */","const matrixFor = (matrix, func) => {","    matrix.forEach((row, i) => {","        row.forEach((item, j) => {","            func(item, i, j, row, matrix);","        });","    })","}","/**"," * 获取矩阵第index个元素 从0开始"," * @param {any[][]} matrix "," * @param {number} index "," */","function getMatrix(matrix, index) {","    let col = matrix[0].length;","    let i = ~~(index / col);","    let j = index - i * col;","    return matrix[i][j];","}","/**"," * 设置矩阵第index个元素 从0开始"," * @param {any[][]} matrix "," * @param {number} index "," */","function setMatrix(matrix, index, value) {","    let col = matrix[0].length;","    let i = ~~(index / col);","    let j = index - i * col;","    return matrix[i][j] = value;","}","/**************** 二叉树 ****************/","/**"," * 二叉树节点"," * @param {*} val"," * @param {TreeNode} left"," * @param {TreeNode} right"," */","function TreeNode(val, left = null, right = null) {","    this.val = val;","    this.left = left;","    this.right = right;","}","/**"," * 通过一个层次遍历的数组生成一棵二叉树"," * @param {any[]} array"," * @return {TreeNode}"," */","function getTreeFromLayerOrderArray(array) {","    let n = array.length;","    if (!n) return null;","    let index = 0;","    let root = new TreeNode(array[index++]);","    let queue = [root];","    while(index < n) {","        let top = queue.shift();","        let v = array[index++];","        top.left = v == null ? null : new TreeNode(v);","        if (index < n) {","            let v = array[index++];","            top.right = v == null ? null : new TreeNode(v);","        }","        if (top.left) queue.push(top.left);","        if (top.right) queue.push(top.right);","    }","    return root;","}","/**"," * 层序遍历一棵二叉树 生成一个数组"," * @param {TreeNode} root "," * @return {any[]}"," */","function getLayerOrderArrayFromTree(root) {","    let res = [];","    let que = [root];","    while (que.length) {","        let len = que.length;","        for (let i = 0; i < len; i++) {","            let cur = que.shift();","            if (cur) {","                res.push(cur.val);","                que.push(cur.left, cur.right);","            } else {","                res.push(null);","            }","        }","    }","    while (res.length > 1 && res[res.length - 1] == null) res.pop(); // 删掉结尾的 null","    return res;","}","/**************** 二分查找 ****************/","/**"," * 寻找>=target的最小下标"," * @param {number[]} nums"," * @param {number} target"," * @return {number}"," */","function lower_bound(nums, target) {","    let first = 0;","    let len = nums.length;","","    while (len > 0) {","        let half = len >> 1;","        let middle = first + half;","        if (nums[middle] < target) {","            first = middle + 1;","            len = len - half - 1;","        } else {","            len = half;","        }","    }","    return first;","}","","/**"," * 寻找>target的最小下标"," * @param {number[]} nums"," * @param {number} target"," * @return {number}"," */","function upper_bound(nums, target) {","    let first = 0;","    let len = nums.length;","","    while (len > 0) {","        let half = len >> 1;","        let middle = first + half;","        if (nums[middle] > target) {","            len = half;","        } else {","            first = middle + 1;","            len = len - half - 1;","        }","    }","    return first;","}",
      "$1"
    ],
    "description": "LeetCode常用代码模板"
  }
}

以后每一次写题之前,键入 @lc 就会出现提示,轻松加入代码模板。

在这里插入图片描述

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

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

相关文章

【C++】stack和queue

文章目录前言&#xff08;重点&#xff09;一、stack1、 stack的介绍2、queue的使用3、stack的模拟实现二、queue1、queue的介绍2、queue的使用3、queue的模拟实现三、容器适配器1、什么是容器适配器呢&#xff1f;2、STL标准库中stack和queue的底层结构四、deque1、deque的原理…

设计模式之单例模式(懒汉, 饿汉)

文章目录一. 单例模式概述二. 单例模式的实现1. 饿汉模式2. 懒汉模式一. 单例模式概述 单例模式是一种常用的软件设计模式, 该模式的主要目的是确保某一个类在内存中只能有一个实例对象, 通过单例模式的方法创建的类在当前进程中只有一个实例对象. 常见的单例模式有两种: 饿…

制作系统安装(微软操作系统系统)

系统安装制作步骤 准备工具&#xff1a;笔记本电脑 8G以上u盘 镜像ISO文件 微软系统下载&#xff1a;https://msdn.itellyou.cn/ 复制连接到迅雷下载&#xff0c;进行系统镜像下载。 U盘制作工具下载和制作&#xff1a; 制作工具网站下载&#xff1a;http://rufus.ie/zh/ 准…

MySQL避免插入重复数据

新建一张测试表&#xff0c;有三个字段&#xff0c;自增主键id、创建了唯一索引的user_name、以及普通字段address。然后插入一条数据作为原始数据&#xff0c;如下所示 1、insert ignore into 基于索引字段数据进行判断&#xff0c;如果索引数据存在&#xff0c;那么忽略本…

CSS单行/多行文本溢出隐藏

前言 在日常开发展示页面&#xff0c;如果一段文本的数量过长&#xff0c;受制于元素宽度的因素&#xff0c;有可能不能完全显示&#xff0c;为了提高用户的使用体验&#xff0c;这个时候就需要我们把溢出的文本显示成省略号 对于文本的溢出&#xff0c;我们可以分成两种形式…

jetson nano安装远程桌面,Qt,pytorch,tensorflow,virtualenv等

文章目录基于jetPack版本4.6.1一.基础组件配置检查二.基础组件安装1.安装pip32.安装python-opencv与机器学习常用包3.安装pytorch方法1&#xff08;失败&#xff09;方法2&#xff08;成功&#xff09;4.安装tensorflow-gpu5.安装QT6.板载摄像头使用7.安装中文输入法8.安装截图…

网络爬虫入门到实战

简介 数据采集文章 开始 入门程序 环境准备 pip3 install beautifulsoup4 基本操作 from urllib.request import urlopen from bs4 import BeautifulSouphtml urlopen("http://www.baidu.com") # print(html.read()) (打印html完整内容) bsObj BeautifulSou…

服务熔断和服务降级

服务之间是可以相互调用的&#xff0c;如果底层的服务出现了问题&#xff0c;那么他的上层服务也就会出问题 为了解决分布式系统的雪崩问题&#xff0c;SpringCloud提供了Hystrix熔断器组件 服务降级 服务降级并不会直接返回错误&#xff0c;而是提供一个补救措施&#xff0c…

简洁明了的ReentrantReadWriteLock总结

&#x1f473;我亲爱的各位大佬们好 ♨️本篇文章记录的为 ReentrantReadWriteLock 相关内容&#xff0c;适合在学Java的小白,帮助新手快速上手,也适合复习中&#xff0c;面试中的大佬&#x1f649;&#x1f649;&#x1f649;。 ♨️如果文章有什么需要改进的地方还请大佬不吝…

王爽汇编(第四版)实验八

文章目录前言一、题目二、分析1.初始时指令存储情况2.运行时指令存储情况总结前言本文是学习王爽老师《汇编语言》(第四版)第九章 实验8 分析一个奇怪的程序 时的相关代码及分析。一、题目分析程序&#xff0c;思考程序是否可以正确返回&#xff1b;运行后再思考&#xff0c;为…

胭脂茉莉点评推荐上海大学法院李本教授诗集《秋月曲》诗歌6首

胭脂茉莉&#xff08;右&#xff09;和李本教授&#xff08;左&#xff09;于2019年冬天在上海留影胭脂茉莉 &#xff0c;女 &#xff0c;江苏人&#xff0c;年少习诗&#xff0c;作家、诗人。评论及随笔见诸媒体及报刊 。诗歌先后被选编入海内外多种选本及刊物&#xff0c;主要…

【我的渲染技术进阶之旅】glfw库简单介绍

文章目录一、为啥去了解glfw?二、glfw相关资料三、glfw简单示例1. 引入 GLFW 头文件2. 初始化和终止 GLFW3. 设置错误回调4. 创建窗口和上下文5.使 OpenGL 上下文成为当前上下文6. 检查窗口关闭标志7.接收输入事件8.使用 OpenGL 渲染9. 读取定时器10.交换缓冲区11. 处理事件12…

【C++】了解设计模式,模拟实现栈和队列

文章目录一.设计模式二.stack的模拟实现三.queue的模拟实现四.了解deque五、题目练习一.设计模式 设计模式有很多种&#xff0c;根据设计模式的参考书 Design Patterns - Elements of Reusable Object-Oriented Software&#xff08;中文译名&#xff1a;设计模式 - 可复用的面…

SpringBoot+VUE前后端分离项目学习笔记 - 【11 SpringBoot代码生成器_MybatisPlus】

引入mp生成器依赖 pom.xml <!-- 代码生成器 --> <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.1</version> </dependency> <dependency><grou…

RabbitMQ 单机安装-CentOS

RabbitMQ 单机安装-CentOS 官网查看RabbitMQ和对应的Erlang版本 进入 RabbitMQ 官网 &#xff0c;点击 顶上的 Get Started 点击Download Installation 点击左侧的Erlang Versions 查看对应版本 根据自己需要安装的RabbitMQ版本&#xff0c;找到需要Erlang的版本。 下…

什么是Spring Cloud?Spring Cloud介绍

简介Spring Cloud项目的官方网址&#xff1a;https://projects.spring.io/spring-cloud/Spring Cloud 并不是一个项目&#xff0c;而是一组项目的集合。在 Spring Cloud中包含了很多的子项目&#xff0c;每一个子项目都是一种微服务开发过程中遇到的问题的一种解决方案。它利用…

红中群内每日分享题目解析——第一天

目录 题目一&#xff1a;最后一次用的英雄 题目二&#xff1a;狗哥去哪 摩斯密码 题目三&#xff1a;黑丝白丝还有什么丝 题目一&#xff1a;最后一次用的英雄 ​​​​​​ 感谢我徒弟(不是 告知并解出此题 杭椒的博客_CSDN博客-网安经验分享,网络安全工具,CISP-PTE备考笔记…

音视频开发常用工具

目录 1.VLC播放器简介 1.1 VLC 播放器 1.2 VLC的功能列表 1.3 VLC播放网络串流 1.4 VLC作为流媒体服务器 2. MediaInfo简介 2.1 MediaInfo 2.1.1 获取多媒体文件信息 2.1.2 支持的格式 2.1.3 .查看方式 2.1.4 国际化 2.2 MediaInfo使用方法 2.3 MediaInfo参数说明 3…

将powershell、cmd和vscode终端的编码永久修改成utf-8

powershell修改方法 1、以管理员身份打开powershe New-Item $PROFILE -ItemType File -Force 2、打开C盘&#xff0c;找到我的文档中的WindowsPowerShell文件夹 3、编辑这个ps1文件&#xff08;默认是空的&#xff09;&#xff0c;加上以下代码 $OutputEncoding [console…

Handler的消息机制与消息延迟代码实现

Handler的作用 Handler消息机制在Android中的应用非常广泛&#xff0c;很多组件的底层实现都是靠Handler来完成的&#xff0c;所以掌握Handler消息机制的原理还是非常重要的。Handler的主要功能有两点&#xff1a; 1.它可以在不同的线程之间传递消息 我们都知道Andorid中规定…