首先要学习一下JS的一些常见的算法基础操作
- 这篇文章是关于 JS算法基础扫盲 我们可以先学习一下JS的一些基础的操作(包括数组、字符串等)。
一、关于栈的相关题目
- 题目链接:20. 有效的括号
var isValid = function (s) {
// 用数组模拟栈
let stack = []
// 如果只有一个元素直接返回false
if (s.length === 1)
return false
// 将第一个元素推入栈中
stack.push(s[0])
// 从第二个元素开始遍历
for (let i = 1; i < s.length; i++) {
// 获取栈顶元素
let top = stack[stack.length - 1]
// 判断栈顶元素和下一个元素是否匹配
if ((top === '{' && s[i] === '}') || (top === '(' && s[i] === ')') || (top === '[' && s[i] === ']')) {
// 出栈
stack.pop()
}
else {
// 入栈
stack.push(s[i])
}
}
// 返回结果
return stack.length === 0
};
2.题目链接:1047. 删除字符串中的所有相邻重复项
var removeDuplicates = function (s) {
//数组模拟栈
let stack = []
// 如果字符串为一个,直接返回
if (s.length == 1) return s
// 将第一个字符串推入栈中
stack.push(s[0])
// 从第二个字符串开始遍历
for (let i = 1; i < s.length; i++) {
// 取出栈顶元素
let top = stack[stack.length - 1]
// 判读栈顶元素是否和下一个字符是否相等
if (top === s[i]) stack.pop()//出栈
else stack.push(s[i])//入栈
}
return stack.join('') //将数组转为字符串
};
将数组转为字符串方法,大家可以看一下这篇文章:文章链接
二、链表
什么是链表:
- 多个元素存储的列表
- 链表中的元素在内存中不是顺序存储的,而是通过next指针联系在一起的。
js中的原型链的原理就是链表结构
// 模拟链表
let a = { key: 1 }
let b = { key: 1 }
let c = { key: 1 }
let d = { key: 1 }
a.next = b
b.next = c
c.next = d
d.next = null
console.log(a);
链表和数组的区别:
- 数组:有序存储的,在中间某个位置添加或者删除某个元素,其他元素也要移动。
- 链表中的元素在内存中不是顺序存储的,而是通过next指针联系在一起的。
分类:单项链表、双向链表、环形链表
链表的一些操作:
遍历链表:
let obj = a
while (obj && obj.key) {
console.log(obj.key)
obj = obj.next
}
// 插入某个元素
let m = { key: 'm' }
c.next = m
m.next = d
console.log(a);
// 删除某个,比如 m 元素
c.next = d
console.log(a);
关于instanceof:
const instanceofs = (target, obj) => {
console.log(obj);
while (target) {
if (target == obj.prototype) {
return true
}
target = target.__proto__
}
return false
}
let arr = [1, 2, 3]
console.log(instanceofs([1, 2], Object));
关于链表的题目:
- 题目链接:141.环形链表
var hasCycle = function (head) {
// 定义两个指针指向头
let f = head, s = head
// 快指针一直循环
while (f != null && f.next != null) {
// 慢指针指向下一个
s = s.next
// 快指针指向下一个
f = f.next.next
// 指针相遇了返回true
if (s == f) return true
}
return false
};
- 题目链接:237.删除链表中的节点
var deleteNode = function (node) {
// 把node的值用下一个节点的值覆盖
node.val = node.next.val
// node的next指向node下下个(node的next的next)
node.next = node.next.next
};
- 题目链接:83.删除排序链表中的重复元素
var deleteDuplicates = function (head) {
// 如果只有一个直接返回
if (!head) return head
let s = head
// 如果有nex就一直循环
while (s.next) {
// 如果当前的值和下一个的值相等
if (s.val == s.next.val) {
// 删除s.next,直接覆盖
s.next = s.next.next
} else {
// 不相等继续指向下一个
s = s.next
}
}
return head
};
- 翻转链表:206.翻转链表
var reverseList = function (head) {
let prev = null
let curr = head
while (curr) {
const next = curr.next
curr.next = prev
prev = curr
curr = next
}
return prev
};
三、字典和哈希表
字典
- 字典:键值对存储的,类似于js的对象(键[key]都是字符串类型或者会转换成字符串类型)
var a = {};
var b = {
key: "a",
};
var c = {
key: "c",
};
a[b] = "123";
a[c] = "456";
console.log(a[b]); //456 b和c对象覆盖
- 字典=》map来表示,map的键不会转换类型
哈希表
- 哈希又叫散列表
- 在js中没有哈希表,哈希表是字典一种体现
两者区别:
- 如果找key对于的value需要遍历key,那么想要省去遍历的过程,用哈希表来表示
- 排列顺序,字典是根据添加的顺序进行排列的,哈希表则不是
手写哈希表(部分 ):
class HashTable {
constructor() {
this.table = [];
}
hashCode(key) {
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash += key.charCodeAt(i);
}
return hash;
}
set(key, val) {
let hashKey = this.hashCode(key);
this.table[hashKey] = val;
}
}
let hashTable = new HashTable();
hashTable.set("person", "lj");
console.log(hashTable);