对字符串、数组的查询调用,一般思路是将字符串、数组提取到对象,再操控对象。
核心算法:
1、将字符存储在一个对象内,给其当属性名,属性值为出现的次数
①利用charAt()遍历字符串
②把每个字符都存储给一个对象,(即当做改对象的属性名)
③判断该对象是否有该属性,没有,赋值1;有,则+1
2、取对象属性值最大值,即可得到字符串中出现最多次的字符以及其出现的次数
①遍历对象
②取最大值
//字符串中最多次的字符以及其次数
var str1 = 'abcabaabcaba';
var obj = {
}
function findMaxDuplicateChar(str) {
if (str.length == 1) {
return str
}
let obj = {
}
for (i = 0; i < str.length; i++) {
let char = str.cahrAt(i)
if(obj[char]) {
obj[char]++
} else {
obj[char] = 1
}
}
// 遍历对象
let maxChar = ''
let maxValue = 1
for(var k in obj) {
if(obj[k] >= maxValue) {
maxChar = k
maxValue = charObj[k]
}
}
return [maxChar, maxChar]
}
回文:指把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。比如 mamam redivider .
核心算法:
利用数组的翻转方式生成新字符串,与原字符串比较。
①字符串 —> 数组
②数组翻转
③数组 —> 字符串
function checkPalindrom(str) {
return str == str.split('').reverse().join('');
}
输入[1,4,5,7,1,8,7,6]
输出[1,4,5,7,8,6]
有两种写法:
①利用对象查找
②利用数组的indexOf()查找
方法一:
function duplicateRemoval(arr) {
let obj = {
}
let newArr = []
for(let i = 0; i < arr.length; i++) {
if(!obj[arr[i]]){
obj[arr[i]] = true
newArr.push(arr[i])
}
}
return newArr
}
方法二.
核心算法:
将数组元素与某一元素比较(一般用为arr[0]),将小于它的元素放在左数组,大于它的元素放在右数组,然后递归进行上一次左右数组的操作,返回合并的数组就是已经排好顺序的数组了。
function quickSort(arr) {
if(arr.length <= 1) {
return arr
}
let leftArr = []
let rightArr = []
let q = arr[0] // 用来比较的元素
// 第一个元素arr[0]不参与比较,不然它会一直卡在第一个位置
for(let i = 1;i < arr.length; i++) {
if(arr[i] < q) {
leftArr.push(arr[i])
} else {
rightArr.push(arr[i])
}
}
// concat 连接数组
return [].concat(quickSort(leftArr), q, quickSort(rightArr))
}
输入 a = 2,b = 4
输出 a = 4,b = 2
核心算法:
主要是利用 +、- 去进行运算,类似 a = a + ( b - a) 实际上等同于最后 的 a = b;
function swap(a, b) {
b = b - a
a = a + b // a = a + b = 原a + (原b - 原a) = 原b
b = a - b // b = a - b = 原b - (原b - 原a) = 原a
return [a, b]
}
核心算法:
Math.random() (产生[0,1]之间的随机数)和 Math.floor() (向下取整)
function randomString(n) {
let str = 'abcdefghijklmnopqrstuvwxyz9876543210' // 先给出26个字母 + 10个个位数数字
let tmp = ''
let i = 0
let l = str.length
for (i = 0; i < n; i++) {
tmp += str.charAt(Math.floor(Math.random() * l));
}
return tmp;
}
给定一个树,给定一个节点id,返回从root到该节点的path、以及该节点的所有叶节点id。
叶节点:最末端的节点。
const exampleTree = {
_id: 1,
children: [{
_id: 2,
children: [{
_id: 4,
children: [{
_id: 7,
children: []
}]
}, {
_id: 5,
children: []
}]
}, {
_id: 3,
children: [{
_id: 6,
children: [{
_id: 8,
children: [{
_id: 10,
children: []
}]
}, {
_id: 9,
children: []
}]
}]
}]
}
//主执行函数
function searchTree(tree, id) {
let res = findNode(tree, id)
//边界处理,输入的id不存在相对应的节点时
if (res == undefined) {
return '在该树的中没有相对应的id的节点'
}
res.path.unshift(tree._id)
let path = res.path.join('-')
let node = res.node // 返回的以该节点为起点的树
let leaves = findLeaves(node)
return {
path,
leaves
}
}
// 深度遍历查找目标节点及缓存相关路径
// 先往某一个节点一直往下查找,找不到再反着一层一层再往下查找
function findNode(tree, id) {
if (tree._id == id) {
console.log(123) // 找到节点
return {
path: [],
node: tree
}
}
console.log(321) // 找不到节点
let res
for (let i = 0; i < tree.children.length; i++) {
res = findNode(tree.children[i], id)
if (res != undefined) {
res.path.unshift(tree.children[i]._id)
return res
}
}
return undefined
}
// 递归获取叶节点
function findLeaves(node) {
if (node.children.length == 0) {
return [node._id]
}
let leaves = []
for (let i = 0; i < node.children.length; i++) {
res = findLeaves(node.children[i])
leaves = res.concat(leaves)
}
return leaves
}
console.log(searchTree(exampleTree, 6));
“vaaabcdde” 子串最长无重复字符长度为4,即"abcd"
var lengthOfLongestSubstring = function(s) {
var res = 0 // 用于存放当前最长无重复子串的长度
var str = "" // 用于存放无重复子串
for(var i = 0; i < s.length; i++) {
var char = s.charAt(i)
var index = str.indexOf(char)
if(index === -1) {
str += char
res = res < str.length ? str.length : res
} else {
// 对无重复子串进行更新
// 遇到重复字符,对str进行更新,因为有res保存最长的长度,所以可以覆盖,只需比较大小即可
str = char
}
}
return res
}