JavaScript刷LeetCode模板技巧篇(一)

虽然很多人都觉得前端算法弱,但其实 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 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值