js算法题

前言

前端算法入门一:刷算法题常用的JS基础扫盲
本篇文章是对于此篇文章的摘录,主要是在里面的内容上加一些自己的理解,帮助自己记忆,所以
才摘录过来,希望大家可以去支持原作者,写的非常好!

我现在才真的明白node.js的作用,那就是当我真的想要用js来写算法题的时候我才发现我没有像java那样的运行环境,只能在浏览器进行调试,可是这样的话就十分的麻烦,所以这个时候node.js就十分有用了,此外,对于用纯js来写算法题还是有很多问题,例如输入和输出,print和input都没有,这些基础的语法我是不会的,这里还需要好好研究一下,真的是一个大问题,在力扣里面,所有的js运行环境都是提供好的,就很方便

刷题基础——输入输出问题

刷题网站解决方案

刷题网站都对输入输出做了处理,我们只需要专注于算法。
在力扣和牛客网中,他们都提供了刷题的输入输出处理,统一的处理方式是提前设置函数,对需要输入的变量设置成参数传入进去,然后应该是后台直接赋值给变量来拿到数据。
以力扣的两数之和为例:
输入输出要求:
在这里插入图片描述
解决方法:
在这里插入图片描述
可以看到是把输入的两个变量作为参数传进去了,同时输出是以

本地输入输出

这个是最难解决的,因为js没有像java那样的sacnner类,所以这里我采用了牛客的方法和网上的一些方法。
采用的方案是使用node.js的readline模块

// 引入readline模块
const { type } = require("os");
const readline = require("readline");
// 不能转换成es模块,node.js识别不了

// 创建readline接口实例
let r1 = readline.createInterface({
    input: process.stdin,
    output: process.stdout
})
// 如果想要拿到输入的数据在函数外处理,则要用异步函数

//调用接口方法
r1.question("请输入\t", function (answer) {
    //  这里有一个问题就是这个answer只能在函数内部获取,所以也就只能在函数内部对输入的数据进行操作了。

    // answer是我们想要获得的输入(默认string类型),接下来就可以对它进行处理获得我们想要的输入了。
    console.log("输入的结果是:", typeof(answer));
    let arr=answer.split(",").map(item=> parseInt(item));
    console.log("输入的结果是:", typeof(arr[0]));
    // 不加close,则不会结束
    r1.close();
   
})

但是这个有一个bug,那就是由于js的执行顺序问题,存在很大的问题,那就是如果我们在内部把answer赋给外面的变量,在外部使用这个变量时,会先执行使用变量这个操作,最后才会执行这个函数里的东西,所以此时就需要用到异步函数。

这里我也使用了chatgpt帮我们去写,真的很智能,危机感十足!

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

const scanner = () => {
  return new Promise(resolve => {
    rl.question('请输入:', answer => {
      resolve(answer);
    });
  });
};

(async () => {
  const input = await scanner();
  console.log('您输入的是:', Object.prototype.toString.call(input).slice(8,-1));
  rl.close();
})();

当我们使用异步函数操作后,第一步是到await 这里来,然后进入scanner函数内部,获取值后再继续后面的输入。这样就轻松解决了js执行顺序的问题。

数组的常用方法

发现一个语法的共同点,很多基础数据结构,例如数组等在各个语言里面的操作是共通的。

push和pop组成栈

先来后出

// 数组模拟常见数据结构之一:栈
const stack = [0, 1]
stack.push(2) // 压栈
console.log(stack) // [0, 1, 2]

const popValue = stack.pop() // 出栈
console.log(popValue) // 2
console.log(stack) // [0, 1]

shift和push组成队列

先入先出

// 数组模拟常见数据结构之一:队列
const queue = [0, 1]
queue.push(2) // 入队
console.log(queue) // [0, 1, 2]

const shiftValue = queue.shift() // 出队
console.log(shiftValue) // 0
console.log(queue) // [1, 2]

unshift()

在头部压入数据,类似于入队,原数组会变。

const arr = [1, 2, 3]
arr.unshift(0)
console.log(arr) // [0, 1, 2, 3]

reverse()

翻转原数组,并返回已完成翻转的数组,原数组改变。注意这一类方法都是改变原数组的

const arr = [1, 2, 3]
console.log(arr.reverse()) // [3, 2, 1]
console.log(arr) // [3, 2, 1]

slice(start,end) (slice:片)

从start 开始截取到end,但是不包括end。
数组的操作好像都是左闭右开的,左边一般都是闭的
不改变原数组

const arr = [1, 2, 3, 4, 5]
console.log(arr.slice(1, 4)) // [2, 3, 4]
console.log(arr) // [1, 2, 3, 4, 5]

splice(start, deleteCount, item1, item2……)(splice:拼接)

它比较复杂的
start参数 开始的位置
deleteCount要截取的个数
后面的items为要添加的元素
如果deleteCount为0,则表示不删除元素,从start位置开始添加后面的几个元素到原始的数组里面。
**返回值为由被删除的元素组成的一个数组。**如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
这个方法会改变原始数组,数组的长度会发生变化
(我觉得要做一个对比的表格,知道哪些方法会改变数组,哪些不会改变)

const arr3 = [1, 2, 3, 4, 5, 6, 7, "f1", "f2"];
const arr4 = arr3.splice(2, 3) // 删除第三个元素以后的三个数组元素(包含第三个元素)
console.log(arr4); // [3, 4, 5];
console.log(arr3); // [1, 2, 6, 7, "f1", "f2"]; 原始数组被改变

const arr5 = arr3.splice(2, 0, "wu", "leon"); 
// 从第2位开始删除0个元素,插入"wu","leon"
console.log(arr5); // [] 返回空数组
console.log(arr3); // [1, 2, "wu", "leon", 6, 7, "f1", "f2"]; 原始数组被改变

const arr6 = arr3.splice(2, 3, "xiao", "long");
// 从第 2 位开始删除 3 个元素,插入"xiao", "long"
console.log(arr6); // ["wu", "leon", 6]
console.log(arr3); //[ 1, 2, "xiao", "long", 7, "f1", "f2"]

const arr7 = arr3.splice(2); // 从第三个元素开始删除所有的元素
console.log(arr7);// ["xiao", "long", 7, "f1", "f2"]
console.log(arr3); // [1, 2]

sort()

对数组的元素进行排序,并返回数组。
默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。
由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。
可参考 MDN:Sort
所以默认是升序,sort((a,b)=>(b-a))则是降序

const arr = [1, 2, 3]
arr.sort((a, b) => b - a) //b-a是降序  a-b是升序
console.log(arr) // [3, 2, 1]

toString()

将数组转化成字符串,并返回该字符串,逗号隔开,原数组不变。

const arr = [1, 2, 3, 4, 5]
console.log(arr.toString()) // ‘1, 2, 3, 4, 5’
console.log(arr) // [1, 2, 3, 4, 5]

join()

将数组转化成字符串,并返回该字符串,不传值则默认逗号隔开,原数组不变。
对于toString(),它更灵活,可以决定用什么隔开。记住这个就好

const arr = [1, 2, 3]
console.log(arr.join()) // ‘1, 2, 3’
console.log(arr) // [1, 2, 3]

可枚举对象

枚举对象:就是键值对的对象,key:value
p1是key(属性),123是value(属性值)

const obj = {
  p1: 123,
  p2: 456
}

js函数

js函数不会对参数进行任何检查,也就是不用定义传入的参数类型,但是新的语法规范最好还是传入参数height:Int()

let在循环内和循环外是不一样的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值