当前位置: 首页 > news >正文

前端js学算法-实践

1、两数之和
const twoSum = (nums, target) => {const obj = {}for (let m = 0; m < nums.length; m++) {const cur = nums[m]const diff = target - curif(obj.hasOwnProperty(diff)){ // 查询对象中是否存在目标值-当前值键值对console.log([obj[diff], m]) // 存在则直接获取差值key对应的值,即索引。m为当前索引break}else{obj[cur] = m // 存储当前值和当前索引}}
}const twoSum = (nums, target) => {const obj = new Map()for (let m = 0; m < nums.length; m++) {const cur = nums[m]const diff = target - curif(obj.has(diff)){console.log([obj.get(diff), m])break}else{obj.set(cur, m)}}
}twoSum([1,2,3,4,5,6,76], 9) // [3, 4]
twoSum([3,3], 6)            // [0, 1]
twoSum([1,2,3,4,5,6,3], 6)  // [1, 3]
2、字母异位词
var strs = ["eat", "tea", "tan", "ate", "nat", "bat"];
var obj = {};
var groupAnagrams = function () {strs.forEach((item) => {const st = item.split("").sort().join("");if (!obj[st]) obj[st] = new Set();obj[st].add(item);});var res = [];Object.values(obj).forEach((item) => {res.push([...item]);});console.log(res);
};
groupAnagrams();
// Output: [ [ 'eat', 'tea', 'ate' ], [ 'tan', 'nat' ], [ 'bat' ] ]
3、最长连续序列
var longestConsecutive = function(nums) {const numsNew = new Set(nums.sort((a,b) => a - b))const arr = []const numsNewList = [...numsNew]numsNewList.forEach((val, index) =>{const nextval = numsNewList[index + 1]const arrlen = arr.lengthconst arrLast = arr[arrlen - 1]if(arrLast){const arrLastlen = arrLast.lengthconst arrLastVal = arrLast[arrLastlen - 1]if(arrLastVal + 1 === val){arrLast.push(val)}else{arr.push([val])}}else{arr.push([val])}})const aaa = arr.sort((a, b) => b.length - a.length);return aaa[0].length
}
4、哈希表与链表

        哈希表是无序的快速查找工具,链表是有序的动态序列容器

    哈希表:

核心特性

  1. 无序性
    • 元素的存储位置由哈希函数计算决定,与插入顺序无关。
    • 遍历时元素的顺序不可预测(取决于哈希桶的分布)。
  2. 快速访问
    • 通过键(Key)直接定位值(Value),时间复杂度接近 O(1)
  3. 存储结构
    • 底层通常是数组 + 链表/红黑树(解决哈希冲突)。
  4. 典型应用
    • 字典、缓存、快速查找场景(如数据库索引)。

js中的对象是基于哈希表结构的,而哈希表的查找时间复杂度为O(1),访问方式:直接通过键访问(O(1))。所以很多人喜欢用对象来做映射,减少遍历循环。

利用数组索引快速查找数据的特性,无序(由哈希函数决定),通过实现一个hash函数将key转化为唯一的索引,对应数组中的一个位置。所以具有快速存取删数据的特性

      优点:

  1. 高效的查找:哈希表可以在常数时间复杂度内进行查找操作,即 O(1)。这使得它在需要快速查询数据的场景中非常有用。

  2. 快速的插入和删除:哈希表同样可以在常数时间复杂度内执行插入和删除操作,这使得它非常适合需要频繁更新数据的场景。

  3. 空间利用率高:哈希表可以根据实际数据量动态调整大小,以尽可能减少内存的使用。

  4. 编码简单:哈希表的实现相对简单,只需设计一个合适的哈希函数即可

      缺点: 

  1. 冲突处理:当两个不同的键被映射到同一个索引位置时,会发生冲突。解决冲突的方法有很多种,但不同的方法对性能的影响也不同。

  2. 哈希函数的选择:选择一个好的哈希函数对于避免冲突以及提高性能至关重要。如果选择的哈希函数不好,可能会导致冲突增多或者性能下降。

  3. 不支持顺序访问:与数组或链表不同,哈希表中的元素没有特定的顺序。如果需要按照某种顺序访问元素,可能需要对哈希表进行额外的处理

	class HashTable {size: numbertable: any[]constructor(size: number) {this.size = sizethis.table = Array.from({length: size}, () => [])}hash(key: string) {let h = 0for (let i = 0; i < key.length; i++) {h += key.charCodeAt(i)}return h % this.size}// 设置和更新set(key, value) {const index = this.hash(key)let bucket = this.table[index]const cur = bucket?.find(item => item.key === key)if (cur) {cur.value = value} else {bucket = []bucket.push({key, value})}}get(key: string) {const index = this.hash(key)const bucket = this.table[index]const cur = bucket?.find(item => item.key === key)return	cur ? cur.value : null}delete(key: string) { const index = this.hash(key)const bucket = this.table[index]const findex = bucket?.findIndex(item => item.key === key)if (findex !== -1) {this.table.splice(findex, 1)return true} else {return false }}has(key) {return !!this.get(key)}}const hashtable = new HashTable(100)hashtable.set('name', 'zhangsan')hashtable.set('age', '20')
    链表:

核心特性

  1. 有序性(按插入顺序)
    • 元素通过节点指针显式连接,遍历顺序始终是插入顺序。
    • 若需要排序,需额外维护(如有序链表)。
  2. 顺序访问
    • 查找元素必须从头节点开始遍历,时间复杂度为 O(n)
  3. 存储结构
    • 节点包含数据(Data)和指针(Next/Prev)。
  4. 典型应用
    • 需要频繁插入/删除的场景(如LRU缓存淘汰算法)

链表格是一种线性数据结构,类似于数组,有序(按插入顺序或显式排序),  访问方式:顺序遍历(O(n))

。但不像数组的元素存储在特定的存储器位置或索引中,链表格的每个元素都是一个独立的对象,其中包含一个指针或链接指向列表中的下一个对象。

每一个元素(通常 称为节点)包含两个项目:存储的数据和到下一个节点的链接,这些数据可以是任何有效数据类型

    优点:

        可以很容易地从链表中删除或添加节点,而无需重组整个数据结构。这是它相对于数组的一个优势

  • 动态内存分配:链表不需要在创建时就确定大小,它可以根据需要动态地增加或减少节点,这使得内存利用更加灵活。

  • 插入和删除效率高:在链表中添加或删除节点时,只需要修改相关节点的指针,不必像数组那样移动大量元素,这样操作起来更快。

  • 灵活性:链表可以轻松地实现各种复杂的数据结构,如双向链表、循环链表等,为不同的算法实现提供了便利

    缺点:

        链表的搜索操作很慢,与数组不同,不允许随机访问数据元素,必须从第一个节点开始按顺序访问节点。由于需要储存指针,相较于数组需要更多内存,

  • 访问效率低:链表不支持随机访问,访问特定位置的节点需要从头开始遍历,这在数据量大时会影响效率1。

  • 额外的内存开销:每个链表节点都需要额外的存储空间来存储指针,这与数组相比是一种空间上的浪费

	class Node{datanextconstrucotr(data) { this.data = data;this.next = null}}class linkedList{headsizeconstryctor() {this.head = nullthis.size = 0}append(data) { const node = new Node(data)if (!this.head) {this.head = node} else {const current = this.headwhile (current.next) {current = current.next}current.next = node}this.size++}// get(data){ // 	const head = this.head// 	while (head.next) {// 		if (head.data === data) {// 			return head.next// 		}// 	}// }delete (data){ if (!this.hear) returnif (this.head.data === data) {this.head = this.head.next} else {let current = this.headlet prev = nullwhile (current && current.data !== data) {current = current.nextprev = current}if (current) {prev.next = current.next}}this.size--}}

相关文章:

  • 可编辑25页PPT | 企业数字底座:数据中台构建路径、方法和实践
  • Vue3源码学习3-结合vitetest来实现mini-vue
  • Java ResourceBundle 资源绑定详解
  • linux find命令妙用
  • Kettle下载安装教程
  • Set系列之HashSet源码分析:原理剖析与实战对比
  • Ubuntu 24.04 终端美化
  • 强化学习之基于无模型的算法之基于值函数的深度强化学习算法
  • 望获实时Linux系统荣获人形机器人技术突破奖
  • 得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践
  • 多通道经颅电刺激器的主流厂家介绍
  • 柯希霍夫积分法偏移成像中数据分布不均匀的处理方法
  • 【题解】Codeforces Round 1019 (Div. 2) B.Binary Typewriter ~ E.Keep the Sum
  • 【赵渝强老师】使用TiDB的审计日志
  • Learning vtkjs之ImageStreamline
  • URP - 公告牌的效果实现
  • 运维仙途 第2章 日志深渊识异常
  • 《多端统一的终极答案:X5内核增强版的渲染优化全解析》
  • AI赋能烟草工艺革命:虫情监测步入智能化时代
  • 栈与队列 Part 6
  • 长三角铁路今日预计发送旅客420万人次,有望创单日客发量新高
  • 孙磊已任中国常驻联合国副代表、特命全权大使
  • 阿迪达斯一季度营收增近13%,称美国加征关税对业绩带来不确定性
  • 成都世运会倒计时100天,中国代表团运动员规模将创新高
  • 卸任兰大校长后,严纯华院士重返北大作报告
  • 专访|首夺天元头衔创生涯历史,王星昊打算一步一步慢慢来