mirror of
https://github.com/142vip/408CSFamily.git
synced 2026-11-03 22:04:15 +08:00
4.29 update coding
This commit is contained in:
BIN
算法/.DS_Store
vendored
BIN
算法/.DS_Store
vendored
Binary file not shown.
44
算法/DeepClone.js
Normal file
44
算法/DeepClone.js
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
|
||||
// 判断数据类型
|
||||
function checkedType(target){
|
||||
// 判断类型 -typeof -instanceof -toString.call() -Array.isArray()
|
||||
return Object.prototype.toString.call(target).slice(8,-1);
|
||||
}
|
||||
|
||||
|
||||
// 基于Json序列化的深拷贝【不能处理函数】
|
||||
function DeepCloneByJSON(target){
|
||||
return JSON.parse(Json.stringify(target))
|
||||
}
|
||||
|
||||
// 基于递归思想的深拷贝
|
||||
function DeepClone(target){
|
||||
|
||||
let result;
|
||||
const targetType=checkType(target);
|
||||
|
||||
if(targetType === 'object'){
|
||||
// 处理对象
|
||||
result={};
|
||||
}else if(targetType === 'Array'){
|
||||
// 处理数组
|
||||
result=[];
|
||||
}else{
|
||||
// 其他数据类型或者函数
|
||||
return result;
|
||||
}
|
||||
|
||||
// 遍历目标数据
|
||||
for(let key in target){
|
||||
// 获取每一项值
|
||||
const value=target[key];
|
||||
|
||||
// 递归处理
|
||||
result[key]=DeepClone(value)
|
||||
}
|
||||
|
||||
|
||||
// 处理完成后,返回
|
||||
return result;
|
||||
}
|
||||
105
算法/GetNumberOfK.js
Normal file
105
算法/GetNumberOfK.js
Normal file
@@ -0,0 +1,105 @@
|
||||
function GetNumberOfK(data, k) {
|
||||
// write code here
|
||||
// 分两次二分查找,知道重复元素首次和最后一次出现位置,相减就能拿到重复次数了.
|
||||
|
||||
// 左侧二分查找,重复元素第一次出现的索引位置
|
||||
const left = leftBinarySearch(data, k);
|
||||
|
||||
|
||||
// 右侧二分查找,重复元素最后一次出现的索引位置
|
||||
const right = rightBinarySearch(data, k);
|
||||
|
||||
console.log(`left:${left}----> right:${right}`)
|
||||
return left === -1 && right === -1 ? 0 : right - left + 1
|
||||
}
|
||||
|
||||
function rightBinarySearch(data, target) {
|
||||
if (!data.length) {
|
||||
return -1
|
||||
}
|
||||
let left = 0;
|
||||
let right = data.length - 1;
|
||||
|
||||
while (left <= right) {
|
||||
|
||||
let mid = left + Math.floor((right - left) / 2);
|
||||
|
||||
if (target === data[mid]) {
|
||||
left = mid + 1
|
||||
} else if (target < data[mid]) {
|
||||
// 左侧
|
||||
right = mid - 1
|
||||
} else if (target > data[mid]) {
|
||||
// 右侧;
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// left = right+1; 判断出界
|
||||
if (right < 0 || data[right] !== target) {
|
||||
return -1
|
||||
}
|
||||
return right
|
||||
}
|
||||
|
||||
|
||||
// [left,right]
|
||||
function leftBinarySearch(data, target) {
|
||||
if (!data.length) {
|
||||
return -1
|
||||
}
|
||||
let left = 0;
|
||||
let right = data.length - 1;
|
||||
|
||||
while (left <= right) {
|
||||
|
||||
let mid = left + Math.floor((right - left) / 2);
|
||||
|
||||
if (target === data[mid]) {
|
||||
// 左侧收缩
|
||||
right = mid - 1;
|
||||
} else if (target < data[mid]) {
|
||||
// 左侧
|
||||
right = mid - 1
|
||||
} else if (target > data[mid]) {
|
||||
// 右侧;
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// left = right+1; 判断出界
|
||||
if (left > data.length || data[left] !== target) {
|
||||
return -1
|
||||
}
|
||||
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
console.log(GetNumberOfK([1, 2, 3, 3, 3, 3, 4, 5], 3))
|
||||
console.log(GetNumberOfK([3, 3, 3, 3, 4, 5], 3))
|
||||
console.log(GetNumberOfK([1, 2, 3, 3, 3, 3], 3))
|
||||
console.log(GetNumberOfK([1, 3, 3, 3, 3, 4, 5], 2))
|
||||
console.log(GetNumberOfK([1, 3, 3, 3, 3, 4, 5], 0))
|
||||
console.log(GetNumberOfK([1, 3, 3, 3, 3, 4, 5], 6))
|
||||
console.log(GetNumberOfK([3, 3, 3, 3], 3))
|
||||
console.log(GetNumberOfK([3, 3, 3, 3], 4))
|
||||
console.log(GetNumberOfK([3], 3))
|
||||
console.log(GetNumberOfK([3], 4))
|
||||
console.log(GetNumberOfK([1, 3, 3, 3, 3, 4, 5], 2))
|
||||
|
||||
|
||||
module.exports = {
|
||||
GetNumberOfK: GetNumberOfK
|
||||
};
|
||||
44
算法/LeftRotateString.js
Normal file
44
算法/LeftRotateString.js
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
function LeftRotateString(str, n) {
|
||||
|
||||
if (!str) {
|
||||
return str;
|
||||
}
|
||||
let arr = str.split('')
|
||||
|
||||
const leftReverseArr = reverse(arr, 0, n - 1);
|
||||
console.log(`left:${leftReverseArr}`)
|
||||
const rightReverseArr = reverse(arr, n, arr.length - 1)
|
||||
console.log(`right:${rightReverseArr}`)
|
||||
|
||||
// 翻转后,通过join连接起来
|
||||
return reverse(arr, 0, arr.length - 1).join('')
|
||||
}
|
||||
|
||||
|
||||
// 数组中翻转
|
||||
function reverse(arr, left, right) {
|
||||
while (left < right) {
|
||||
// 元素交换
|
||||
arr = swap(arr, left, right)
|
||||
// left右移
|
||||
left++
|
||||
// right左移
|
||||
right--
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
// 元素交换
|
||||
function swap(arr, left, right) {
|
||||
|
||||
const temp = arr[left];
|
||||
arr[left] = arr[right];
|
||||
arr[right] = temp
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
console.log(LeftRotateString('', 6))
|
||||
61
算法/QuickSort.js
Normal file
61
算法/QuickSort.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 非递归实现快速排序
|
||||
* @param {*} data
|
||||
* @param {*} low
|
||||
* @param {*} high
|
||||
*/
|
||||
function quickSort(data, low, high) {
|
||||
console.log(data, low, high)
|
||||
const pivot = partition(data, low, high);
|
||||
let result = [];
|
||||
|
||||
if (pivot + 1 < high) {
|
||||
result.push(pivot + 1, high);
|
||||
} else if (pivot > low + 1) {
|
||||
result.push(low, pivot - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 数组不为空
|
||||
while (result.length > 0) {
|
||||
console.log(1, result)
|
||||
const temp_high = result.pop();
|
||||
const temp_low = result.pop();
|
||||
if (temp_low >= temp_high) {
|
||||
break;
|
||||
}
|
||||
const temp_pivot = partition(data, temp_low, temp_high);
|
||||
|
||||
if (temp_pivot + 1 < high) {
|
||||
result.push(temp_pivot + 1, temp_high)
|
||||
} else if (temp_pivot - 1 > low) {
|
||||
result.push(temp_low, temp_pivot - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 严版获取快排pivot
|
||||
function partition(data, low, high) {
|
||||
|
||||
let pivot = data[low];
|
||||
|
||||
while (low < high) {
|
||||
// 高位
|
||||
while (low < high && pivot <= data[high]) --high;
|
||||
data[low] = data[high]
|
||||
// 低位
|
||||
while (low < high && pivot >= data[low]) ++low;
|
||||
data[high] = data[low]
|
||||
}
|
||||
data[low] = pivot
|
||||
|
||||
return low
|
||||
}
|
||||
|
||||
console.log(quickSort([1, 8, 9, 2], 0, 3))
|
||||
56
算法/find.js
Normal file
56
算法/find.js
Normal file
@@ -0,0 +1,56 @@
|
||||
function Find(target, array) {
|
||||
// write code here
|
||||
if (!array) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 行
|
||||
const rows = array.length;
|
||||
// 列
|
||||
const cols = array[0].length;
|
||||
console.log(rows, cols)
|
||||
if (rows === 0 || cols === 0) {
|
||||
return false;
|
||||
}
|
||||
let r = 0,
|
||||
c = cols - 1;
|
||||
|
||||
while (r < rows && c >= 0) {
|
||||
|
||||
if (array[r][c] === target) {
|
||||
return true;
|
||||
} else if (array[r][c] < target) {
|
||||
// 比目标值小,往下
|
||||
r++
|
||||
} else if (array[r][c] > target) {
|
||||
// 比目标值大 往左
|
||||
c--
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
console.log(Find(7, [
|
||||
[1, 2, 8, 9],
|
||||
[2, 4, 9, 12],
|
||||
[4, 7, 10, 13],
|
||||
[6, 8, 11, 15]
|
||||
]))
|
||||
|
||||
// 投机方案
|
||||
function Find01() {
|
||||
const len = array.length;
|
||||
let result = []
|
||||
for (let index = 0; index < len; index++) {
|
||||
result = result.concat(array[index]);
|
||||
}
|
||||
console.log(result, result.indexOf(target));
|
||||
// 查询
|
||||
return result.indexOf(target) !== -1
|
||||
}
|
||||
module.exports = {
|
||||
Find: Find
|
||||
};
|
||||
22
算法/global_variables.js
Normal file
22
算法/global_variables.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
global.config = require('config');
|
||||
global.fse = require('fs-extra');
|
||||
global.fs = require('fs');
|
||||
global.path = require('path');
|
||||
global.errorHandler = require('./middleware/errorHandler').errorHandler;
|
||||
global.utils = require('./tools/utils');
|
||||
|
||||
global.mainlogger = require('./logger/logger').mainlogger;
|
||||
global.weblogger = require('./logger/logger').weblogger;
|
||||
|
||||
global.strCache = require('./cache').caches.strCache;
|
||||
|
||||
global.hashCache = require('./cache').caches.hashCache;
|
||||
global.helper = require('./controller/helper');
|
||||
|
||||
global.requests = require('./tools/request');
|
||||
|
||||
|
||||
|
||||
|
||||
43
算法/isUSD.js
Normal file
43
算法/isUSD.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const {
|
||||
lstat
|
||||
} = require("fs-extra");
|
||||
|
||||
function isUSD(str) {
|
||||
if (!str.startsWith("$")) {
|
||||
return false;
|
||||
}
|
||||
str = str.slice(1);
|
||||
if (str.indexOf(".") !== -1) {
|
||||
// 小数
|
||||
let arr = str.split(".");
|
||||
if (arr[1].length !== 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let strArr = arr[0].split(",");
|
||||
if (strArr[0].length > 3) {
|
||||
return false;
|
||||
}
|
||||
for (let index = 1; index < strArr.length; index++) {
|
||||
if (strArr[index].length !== 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
let strArr = str.split(",");
|
||||
if (strArr[0].length > 3) {
|
||||
return false;
|
||||
}
|
||||
for (let index = 1; index < strArr.length; index++) {
|
||||
if (strArr[index].length !== 3) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
lstat
|
||||
}
|
||||
|
||||
console.log(isUSD("$,344.34"));
|
||||
40
算法/merge.js
Normal file
40
算法/merge.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* @param A int整型一维数组
|
||||
* @param B int整型一维数组
|
||||
* @return void
|
||||
*/
|
||||
function merge(A, m, B, n) {
|
||||
// write code here
|
||||
|
||||
let pre = 0,
|
||||
next = 0;
|
||||
let result = []
|
||||
while (pre < m && next < n) {
|
||||
if (A[pre] < B[next]) {
|
||||
result.push(A[pre])
|
||||
pre++
|
||||
} else if (A[pre] >= B[next]) {
|
||||
result.push(B[next])
|
||||
next++
|
||||
}
|
||||
}
|
||||
console.log(result, pre, next)
|
||||
// A的元素都遍历完了,B没有遍历完,next<n,将后面的元素都追加到result后面
|
||||
if (pre === m) {
|
||||
|
||||
// 连接后要重新赋值
|
||||
result = result.concat(B.slice(next))
|
||||
}
|
||||
// B的元素都遍历完了
|
||||
if (next === n) {
|
||||
result = result.concat(A.slice(pre))
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
module.exports = {
|
||||
merge: merge
|
||||
};
|
||||
|
||||
console.log(merge([], 0, [1], 1))
|
||||
72
算法/mergeLink.js
Normal file
72
算法/mergeLink.js
Normal file
@@ -0,0 +1,72 @@
|
||||
function ListNode(x) {
|
||||
this.val = x;
|
||||
this.next = null;
|
||||
}
|
||||
|
||||
function Merge1(pHead1, pHead2) {
|
||||
// write code here
|
||||
// 单调不减 可以理解 等于或者大于递增
|
||||
let p1 = pHead1,
|
||||
p2 = pHead2;
|
||||
let result = {};
|
||||
// 保留头指针
|
||||
let kk = result;
|
||||
while (p1 !== null && p2 !== null) {
|
||||
// console.log(p1,p2)
|
||||
if (p1.val <= p2.val) {
|
||||
// 左边小
|
||||
kk.next = p1;
|
||||
p1 = p1.next
|
||||
} else {
|
||||
kk.next = p2;
|
||||
p2 = p2.next
|
||||
}
|
||||
console.log(p1, p2)
|
||||
}
|
||||
|
||||
console.log('test:', result, kk)
|
||||
|
||||
console.log('go:', p1, p2)
|
||||
console.log('go1:', pHead1, pHead2)
|
||||
if (p1) {
|
||||
kk.next = p1;
|
||||
}
|
||||
if (p2) {
|
||||
kk.next = p2;
|
||||
}
|
||||
console.log(kk)
|
||||
return result.next
|
||||
|
||||
}
|
||||
|
||||
function Merge(pHead1, pHead2) {
|
||||
// write code here
|
||||
let vhead = {};
|
||||
let cur = vhead;
|
||||
while (pHead1 && pHead2) {
|
||||
if (pHead1.val <= pHead2.val) {
|
||||
cur.next = pHead1;
|
||||
pHead1 = pHead1.next;
|
||||
} else {
|
||||
cur.next = pHead2;
|
||||
pHead2 = pHead2.next;
|
||||
}
|
||||
cur = cur.next;
|
||||
}
|
||||
cur.next = pHead1 ? pHead1 : pHead2;
|
||||
return vhead.next;
|
||||
}
|
||||
|
||||
let pre = new ListNode(1);
|
||||
pre.next = new ListNode(3);
|
||||
pre.next.next = new ListNode(5)
|
||||
console.log('pre:', pre)
|
||||
|
||||
let last = new ListNode(2);
|
||||
last.next = new ListNode(4);
|
||||
last.next.next = new ListNode(6)
|
||||
console.log('last:', last)
|
||||
console.log(Merge(pre, last))
|
||||
module.exports = {
|
||||
Merge: Merge
|
||||
};
|
||||
25
算法/spiralOrder.js
Normal file
25
算法/spiralOrder.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* @param matrix int整型二维数组
|
||||
* @return int整型一维数组
|
||||
*/
|
||||
function spiralOrder(matrix) {
|
||||
// write code here
|
||||
|
||||
const high = matrix.length;
|
||||
const width = matrix[0].length;
|
||||
|
||||
let top = width
|
||||
let bottom = width
|
||||
let right = high
|
||||
let left = high
|
||||
}
|
||||
module.exports = {
|
||||
spiralOrder: spiralOrder
|
||||
};
|
||||
|
||||
consle.log(spiralOrder([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
]))
|
||||
42
算法/straightInsertSort.js
Normal file
42
算法/straightInsertSort.js
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
/**
|
||||
* ++i 和 i++ 的区别: https://zhidao.baidu.com/question/40433825.html
|
||||
*/
|
||||
|
||||
function straightInsertSort(arr,len){
|
||||
len=arr.length===len?len:arr.length;
|
||||
// console.log(len)
|
||||
for(let i=1;i<len;i++){
|
||||
// 前面的元素比后面的元素大
|
||||
if(arr[i]<arr[i-1]){
|
||||
|
||||
// 交换排序
|
||||
// let j=i
|
||||
// for(j;j>0;j--){
|
||||
// if(arr[j-1]>arr[j]){
|
||||
// const temp=arr[j]
|
||||
// arr[j]=arr[j-1]
|
||||
// arr[j-1]=temp;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 插入排序
|
||||
const temp=arr[i];
|
||||
let j;
|
||||
// 哨兵元素小于前面的倒叙元素
|
||||
for(j=i-1;arr[j]>temp;--j){
|
||||
arr[j+1]=arr[j]
|
||||
}
|
||||
arr[j+1]=temp
|
||||
// console.log(arr)
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
const straightInsertSortResult= straightInsertSort([3,16,5,7,1,9,40,18,24],9)
|
||||
console.log(straightInsertSort([3,16,5,7,1],5))
|
||||
|
||||
console.log(straightInsertSortResult)
|
||||
|
||||
24
算法/test.js
Normal file
24
算法/test.js
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
function debounce(func,time){
|
||||
let timeout
|
||||
return ()=>{
|
||||
clearTimeout(timeout)
|
||||
timeout=setTimeout(()=>{
|
||||
func.apply(this,arguments)
|
||||
// func()
|
||||
},time)
|
||||
}
|
||||
}
|
||||
|
||||
function test(){
|
||||
console.log(new Date().getTime())
|
||||
}
|
||||
|
||||
const debounce_test= debounce(test,1000)
|
||||
debounce_test()
|
||||
|
||||
debounce_test()
|
||||
// setTimeout(()=>{
|
||||
// dou(test,1000)
|
||||
// },1500)
|
||||
91
算法/twoNums.js
Normal file
91
算法/twoNums.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 给出一个整数数组, 请在数组中找出两个加起来等于目标值的数,
|
||||
你给出的函数twoSum 需要返回这两个数字的下标( index1, index2), 需要满足 index1 小于index2.。注意: 下标是从1开始的
|
||||
假设给出的数组中只存在唯一解
|
||||
*/
|
||||
|
||||
function twoSum(numbers, target) {
|
||||
// write code here
|
||||
for (let i = 0; i = numbers.length - 1; i++) {
|
||||
const num = numbers[i];
|
||||
const value = target - num
|
||||
if (numbers.indexOf(target - num, i)) {
|
||||
return [i + 1, numbers.indexOf(target - num) + 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
twoSum: twoSum
|
||||
};
|
||||
|
||||
|
||||
function captureThreeNumbers(str) {
|
||||
// 切割转化
|
||||
const arr = str.split('');
|
||||
console.log(arr)
|
||||
const num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
|
||||
for (let index = 0; index < arr.length - 1; index++) {
|
||||
if (num.includes(arr[index]) && num.includes(arr[index + 1]) && num.includes(arr[index + 2])) {
|
||||
return parseInt(`${arr[index]}${arr[index+1]}${arr[index+2]}`)
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
console.log(captureThreeNumbers('abc123'))
|
||||
|
||||
|
||||
function matchesPattern(str) {
|
||||
|
||||
|
||||
if (str.length !== 12) {
|
||||
return false;
|
||||
}
|
||||
// console.log(str.slice(2, 3), str.slice(6, 7))
|
||||
if (str.slice(3, 4) !== '-' || str.slice(7, 8) !== '-') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const arr = str.split('-');
|
||||
console.log(arr)
|
||||
if (arr.length !== 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [low, mid, high] = arr;
|
||||
|
||||
const rule = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
|
||||
const lowArr = low.split('');
|
||||
const midArr = mid.split('');
|
||||
const highArr = high.split('');
|
||||
|
||||
console.log(lowArr, midArr, highArr)
|
||||
|
||||
// 逐一比对
|
||||
|
||||
for (let index = 0; index < lowArr.length; index++) {
|
||||
if (!rule.includes(lowArr[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < midArr.length; index++) {
|
||||
if (!rule.includes(midArr[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < highArr.length; index++) {
|
||||
if (!rule.includes(highArr[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log(matchesPattern('800-555-1212'))
|
||||
65
算法/前端/Readme.md
Normal file
65
算法/前端/Readme.md
Normal file
@@ -0,0 +1,65 @@
|
||||
<!--
|
||||
* @Description: 关于前端算法刷题
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 07:33:14
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 07:41:15
|
||||
-->
|
||||
|
||||
|
||||
## 前端算法刷题
|
||||
|
||||
> 相比后端涉及到的算法,前端的算法较为基础,常常是用来解决某个场景的问题
|
||||
|
||||
- 刷题平台: [牛客网](https://www.nowcoder.com/ta/front-end)
|
||||
- 语言版本:JavaScript
|
||||
|
||||
|
||||
|
||||
### 入门
|
||||
|
||||
|
||||
- dom 节点查找
|
||||
- 根据包名,在指定空间中创建对象
|
||||
- 斐波那契数列
|
||||
- 字符串字符统计
|
||||
- 数组求和
|
||||
- 删除数组最后一个元素
|
||||
- 添加元素
|
||||
- 删除数组第一个元素
|
||||
- 数组合并
|
||||
- 计数
|
||||
- 求二次方
|
||||
- 查找元素位置
|
||||
- 避免全局变量
|
||||
- 正确的使用
|
||||
- 完全等同
|
||||
- 函数传参
|
||||
- 函数的上下文
|
||||
- 二次封装函数
|
||||
- 使用 arguments
|
||||
- 柯里化
|
||||
- 或运算
|
||||
- 且运算
|
||||
- 二进制转换
|
||||
- 乘法
|
||||
- 改变上下文
|
||||
- 批量改变对象的属性
|
||||
- 判断是否包含数字
|
||||
- 判断是否以元音字母结尾
|
||||
### 简单
|
||||
|
||||
|
||||
### 中等
|
||||
|
||||
|
||||
### 较难
|
||||
|
||||
|
||||
|
||||
|
||||
### 困难
|
||||
|
||||
在牛客网题库——前端大挑战中暂时没有标记为`困难`的题目,个人觉得按照常用的场景,把前面的几个分类刷完就ok了,没事多刷刷呗
|
||||
|
||||
123
算法/剑指/Readme.md
123
算法/剑指/Readme.md
@@ -4,11 +4,11 @@
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-27 08:39:46
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-28 22:27:46
|
||||
* @LastEditTime: 2021-04-29 22:09:29
|
||||
-->
|
||||
|
||||
|
||||
## 算法
|
||||
## 剑指Offer算法
|
||||
|
||||
> 刷题平台:牛客网
|
||||
> 语言版本:JavaScript
|
||||
@@ -22,4 +22,121 @@
|
||||
- [【简单】第一个只出现一次的字符位置](./数组和矩阵/FirstNotRepeatingChar.js)
|
||||
|
||||
|
||||
### 栈队列堆
|
||||
### 栈队列堆
|
||||
|
||||
- [【简单】两个栈实现队列](./栈队列堆/JSStackToQueue.js)
|
||||
- [【中等】最小的k个数](./栈队列堆/GetLeastNumbers_Solution.js)
|
||||
- [【中等】数据流中的中位数](./栈队列堆/InsertAndGetMedian.js)
|
||||
- [【中等】字符流中的第一个不重复的字符](./栈队列堆/FirstAppearingOnce.js)
|
||||
- [【较难】滑动窗口的最大值](./栈队列堆/maxInWindows.js)
|
||||
- [【较难】包含min函数的栈](./栈队列堆/GetMinInJSStack.js)
|
||||
- 栈的压入、弹出序列
|
||||
|
||||
|
||||
|
||||
### 双指针
|
||||
|
||||
- 【中等】和为S的两个数字
|
||||
- 和为S的连续正数序列
|
||||
- 翻转单词顺序列
|
||||
- 左旋转字符串
|
||||
|
||||
|
||||
### 链表
|
||||
|
||||
- 从尾到头打印链表
|
||||
- 在O(1)时间内删除链表节点
|
||||
- 删除链表中重复的结点
|
||||
- 链表中倒数第K个结点
|
||||
- 链表中环的入口结点
|
||||
- 反转链表
|
||||
- 合并两个排序的链表
|
||||
- 复杂链表的复制
|
||||
- 两个链表的第一个公共结点
|
||||
|
||||
|
||||
### 树
|
||||
|
||||
- 重建二叉树
|
||||
- 二叉树的下一个结点
|
||||
- 树的子结构
|
||||
- 二叉树的镜像
|
||||
- 对称的二叉树
|
||||
- 从上往下打印二叉树
|
||||
- 把二叉树打印成多行
|
||||
- 二叉搜索树的后续遍历序列
|
||||
- 二叉树中和为某一值的路劲
|
||||
- 二叉搜索树和双向链表
|
||||
- 序列化二叉树
|
||||
- 二叉查找树的第K个结点
|
||||
- 二叉树的深度
|
||||
- 平衡二叉树
|
||||
- 树中两个节点的最低公共祖先
|
||||
|
||||
|
||||
### 贪心思想
|
||||
|
||||
- 剪绳子
|
||||
- 股票的最大利润
|
||||
|
||||
|
||||
### 二分查找
|
||||
|
||||
- 旋转数组的最小数字
|
||||
- 数字在排序数组中出现的次数
|
||||
|
||||
|
||||
### 分治
|
||||
|
||||
- 数值的整数次方
|
||||
|
||||
|
||||
### 搜索
|
||||
|
||||
- 矩阵中的路劲
|
||||
- 机器人的运动范围
|
||||
- 字符串的排列
|
||||
|
||||
|
||||
### 排列
|
||||
|
||||
- 调整数组顺序使奇数位于偶数前面
|
||||
- 把数组排成最小的数
|
||||
- 数组中的逆序对
|
||||
|
||||
### 动态规划
|
||||
|
||||
- 斐波拉契数列
|
||||
- 矩形覆盖
|
||||
- 跳台阶
|
||||
- 变态跳台阶
|
||||
- 连续子数组的最大和
|
||||
- 礼物的最大价值
|
||||
- 最长不含重复字符的子字符串
|
||||
- 丑数
|
||||
- n个骰子的点数
|
||||
- 构建乘积数组
|
||||
|
||||
|
||||
### 数学
|
||||
|
||||
- 数组中出现次数超过一半的数字
|
||||
- 圆圈中最后剩下的数
|
||||
- 从1到n整数中1出现的次数
|
||||
|
||||
### 位运算
|
||||
|
||||
- 二进制中1的个数
|
||||
- 数组中只出现一次的数字
|
||||
|
||||
### 其他
|
||||
|
||||
- 打印从 1 到最大的 n 位数
|
||||
- 正则表达式匹配
|
||||
- 表示数值的字符串
|
||||
- 数字序列中的某一位数字
|
||||
- 把数字翻译成字符串
|
||||
- 扑克牌顺子
|
||||
- 求 1+2+3+...+n
|
||||
- 不用加减乘除做加法
|
||||
- 把字符串转换成整数
|
||||
27
算法/剑指/thenumberof0.js
Normal file
27
算法/剑指/thenumberof0.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 22:43:05
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 22:44:23
|
||||
*/
|
||||
function thenumberof0( n ) {
|
||||
// write code here
|
||||
let result=1;
|
||||
let count=0;
|
||||
for(let index=1;index<=n;index++){
|
||||
result *= index;
|
||||
if(result%10===0){
|
||||
count++;
|
||||
// 避免溢出
|
||||
result /=10;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
console.log(thenumberof0(10000000))
|
||||
module.exports = {
|
||||
thenumberof0 : thenumberof0
|
||||
};
|
||||
8
算法/剑指/动态规划/jumpFloor.js
Normal file
8
算法/剑指/动态规划/jumpFloor.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-28 23:41:55
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-28 23:41:55
|
||||
*/
|
||||
8
算法/剑指/动态规划/jumpFloorII.js
Normal file
8
算法/剑指/动态规划/jumpFloorII.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-28 23:41:50
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-28 23:41:51
|
||||
*/
|
||||
44
算法/剑指/栈队列堆/FirstAppearingOnce.js
Normal file
44
算法/剑指/栈队列堆/FirstAppearingOnce.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @Description: 【中等】字符流中的第一个不重复的字符
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 21:40:02
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 21:47:24
|
||||
*/
|
||||
|
||||
//Init module if you need
|
||||
let result;
|
||||
function Init () {
|
||||
// write code here
|
||||
result = '';
|
||||
}
|
||||
//Insert one char from stringstream
|
||||
function Insert (ch) {
|
||||
// write code here
|
||||
result += ch
|
||||
return result
|
||||
}
|
||||
//return the first appearence once char in current stringstream
|
||||
function FirstAppearingOnce () {
|
||||
// write code here
|
||||
for (let index = 0; index < result.length; index++) {
|
||||
//
|
||||
const str = result[index];
|
||||
|
||||
// 注意这里遍历,str字符要么只有一个,不存在找不到为-1的情况,因为str从字符中截取的
|
||||
if (result.indexOf(str) === result.lastIndexOf(str)) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
// 没有返回
|
||||
return '#'
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Init: Init,
|
||||
Insert: Insert,
|
||||
FirstAppearingOnce: FirstAppearingOnce
|
||||
};
|
||||
43
算法/剑指/栈队列堆/GetLeastNumbers_Solution.js
Normal file
43
算法/剑指/栈队列堆/GetLeastNumbers_Solution.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Description: 最小的K个数
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-28 23:12:33
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-28 23:35:30
|
||||
*/
|
||||
|
||||
|
||||
function GetLeastNumbers_Solution (input, k) {
|
||||
// write code here
|
||||
// 偷懒做法
|
||||
return k > input.length ? [] : input.sort((a, b) => a - b).slice(0, k)
|
||||
}
|
||||
|
||||
// 基于冒泡实现
|
||||
function GetLeastNumbers_Solution01 (input, k) {
|
||||
// write code here
|
||||
|
||||
// 添加参数校验
|
||||
if (k > input.length) {
|
||||
return []
|
||||
}
|
||||
// 先将输入的数组进行排序从小到大 只拍前面几个即可
|
||||
// 这里首先想到的是冒泡或者插入排序里面的特性 --- 每次都有一个元素在最终的位置上
|
||||
|
||||
// 循环k次,跑k趟
|
||||
for (let index = 0; index < k; index++) {
|
||||
for (let j = input.length - 1; j > index; j--) {
|
||||
if (input[index] > input[j]) {
|
||||
// 找到比它的,位置交换
|
||||
[input[index], input[j]] = [input[j], input[index]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 排序完毕,输入前k个
|
||||
return input.slice(0, k)
|
||||
}
|
||||
module.exports = {
|
||||
GetLeastNumbers_Solution: GetLeastNumbers_Solution
|
||||
};
|
||||
41
算法/剑指/栈队列堆/GetMinInJSStack.js
Normal file
41
算法/剑指/栈队列堆/GetMinInJSStack.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Description: 【较难】包含min函数的栈
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 22:04:17
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 22:04:36
|
||||
*/
|
||||
|
||||
|
||||
|
||||
let result = [];
|
||||
function push (node) {
|
||||
// write code here
|
||||
if (result) {
|
||||
return result.push(node)
|
||||
}
|
||||
}
|
||||
function pop () {
|
||||
// write code here
|
||||
if (result.length > 0) {
|
||||
return result.pop();
|
||||
}
|
||||
}
|
||||
function top () {
|
||||
// write code here
|
||||
if (result.length > 0) {
|
||||
return result[result.length - 1]
|
||||
}
|
||||
}
|
||||
function min () {
|
||||
// write code here
|
||||
// 对result数组进行排序
|
||||
return Math.min(...result)
|
||||
}
|
||||
module.exports = {
|
||||
push: push,
|
||||
pop: pop,
|
||||
top: top,
|
||||
min: min
|
||||
};
|
||||
40
算法/剑指/栈队列堆/InsertAndGetMedian.js
Normal file
40
算法/剑指/栈队列堆/InsertAndGetMedian.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Description: 【中等】数据流中的中位数
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 21:38:01
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 21:39:13
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// 存储数据
|
||||
let result = [];
|
||||
function Insert (num) {
|
||||
// write code here
|
||||
result.push(num)
|
||||
// 当然,也可以在push之后去排序
|
||||
}
|
||||
function GetMedian () {
|
||||
// write code here
|
||||
// 先排序
|
||||
result = result.sort((a, b) => a - b);
|
||||
let len = result.length;
|
||||
|
||||
// 奇数
|
||||
if (len % 2 !== 0) {
|
||||
return result[Math.floor((len - 1) / 2)]
|
||||
} else {
|
||||
// 分别获取低位 和高位
|
||||
const low = result[Math.floor((len - 2) / 2)]
|
||||
const high = result[Math.floor((len) / 2)]
|
||||
|
||||
// 去平均值
|
||||
return (high + low) / 2
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
Insert: Insert,
|
||||
GetMedian: GetMedian
|
||||
};
|
||||
24
算法/剑指/栈队列堆/JSStackToQueue.js
Normal file
24
算法/剑指/栈队列堆/JSStackToQueue.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* @Description: 【简单】用两个栈实现队列
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 22:06:51
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 22:07:22
|
||||
*/
|
||||
|
||||
let result = []
|
||||
function push (node) {
|
||||
// write code here
|
||||
// 尾部进栈
|
||||
result.push(node)
|
||||
}
|
||||
function pop () {
|
||||
// write code here
|
||||
// 队列 先进先出 头部出去
|
||||
return result.shift()
|
||||
}
|
||||
module.exports = {
|
||||
push: push,
|
||||
pop: pop
|
||||
};
|
||||
28
算法/剑指/栈队列堆/maxInWindows.js
Normal file
28
算法/剑指/栈队列堆/maxInWindows.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* @Description: 【较难】滑动窗口的最大值
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 21:49:42
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 21:58:32
|
||||
*/
|
||||
|
||||
function maxInWindows (num, size) {
|
||||
// write code here
|
||||
let len = num.length;
|
||||
let result = [];
|
||||
if (len < size || size === 0) {
|
||||
// 窗口大于数组长度 || 窗口大小为0
|
||||
return []
|
||||
}
|
||||
|
||||
for (let index = 0; index <= len - size; index++) {
|
||||
|
||||
// 获取最大值 【这里可以抽一个多数求最大的函数出来】
|
||||
result.push(Math.max(...num.slice(index, index + size)))
|
||||
}
|
||||
return result;
|
||||
}
|
||||
module.exports = {
|
||||
maxInWindows: maxInWindows
|
||||
};
|
||||
34
算法/剑指/贪心思想/maxProfit.js
Normal file
34
算法/剑指/贪心思想/maxProfit.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* @Description: 买卖股票的最好时机
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2021-04-29 23:27:18
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2021-04-29 23:27:55
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @param prices int整型一维数组
|
||||
* @return int整型
|
||||
*/
|
||||
function maxProfit (prices) {
|
||||
// write code here
|
||||
// 最低点买入,最高点卖出,收益最大 实际求的是一个子序列,最大和最小的差值 最小在前,最大在后
|
||||
|
||||
// 最大收益为0 其他都不算收益
|
||||
let max = 0;
|
||||
|
||||
for (let index = 0; index < prices.length; index++) {
|
||||
let start = prices[index];
|
||||
let end = Math.max(...prices.slice(index + 1));
|
||||
if (end - start > max) {
|
||||
max = end - start;
|
||||
}
|
||||
}
|
||||
|
||||
// 返回最大值
|
||||
return max;
|
||||
}
|
||||
module.exports = {
|
||||
maxProfit: maxProfit
|
||||
};
|
||||
Reference in New Issue
Block a user