1
0
mirror of https://github.com/142vip/408CSFamily.git synced 2026-07-11 01:26:42 +08:00

Merge pull request #15 from mmdapl/feat/code-style

refactor: eslint规则,删除无用算法代码
This commit is contained in:
Rong姐姐好可爱
2023-03-02 22:30:32 +08:00
committed by GitHub
123 changed files with 397 additions and 6055 deletions

7
.eslintignore Normal file
View File

@@ -0,0 +1,7 @@
node_modules
manuscript
.github
.idea
.dockerignore
.gitignore

169
.eslintrc.js Normal file
View File

@@ -0,0 +1,169 @@
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'plugin:vue/essential',
'standard'
],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: [
'vue',
'@typescript-eslint'
],
rules: {
'no-unused-vars': 0,
'arrow-spacing': [2, {
before: true,
after: true
}], // 箭头函数中的箭头前后加空格
'block-spacing': [2, 'always'], // 花括号内前后加空格
'brace-style': [2, '1tbs', {
allowSingleLine: true
}], // 允许单行方法
'comma-dangle': [2, 'never'], // 在对象、数组文字中不使用尾随逗号
'comma-spacing': [2, {
before: false,
after: true
}], // 逗号后空格
'comma-style': [2, 'last'], // 对象、数组元素同一行后面加逗号
'constructor-super': 2, // 派生类的构造函数必须调用super()
curly: [2, 'multi-line'], // 方法体多行不允许省略花括号
'dot-location': [2, 'property'], // 点与属性在同一行
'eol-last': 2, // 在非空文件的末尾强制使用至少一个换行符
'generator-star-spacing': [2, {
before: true,
after: true
}], // 生成器函数前后加空格
'handle-callback-err': [2, '^(err|error)$'], // err的错误回调必须处理
'key-spacing': [2, {
beforeColon: false,
afterColon: true
}], // 对象字面亮键和冒号之间存在空格
'keyword-spacing': [2, {
before: true,
after: true
}],
'new-cap': [2, {
newIsCap: true,
capIsNew: false
}], // 构造函数首字母大写
'no-class-assign': 2, // 禁止修改类申明的变量
'no-cond-assign': 2, // 禁止条件表达式中出现赋值操作符
'no-const-assign': 2, // 禁止修改 const 声明的变量
'no-delete-var': 2, // 禁止删除变量
'no-dupe-args': 2, // 禁止 function 定义中出现重名参数
'no-dupe-class-members': 2, // 禁止类成员中出现重复的名称
'no-dupe-keys': 2, // 禁止对象字面量中出现重复的 key
'no-duplicate-case': 2, // 禁止出现重复的 case 标签
'no-empty-character-class': 2, // 禁止在正则表达式中使用空字符集
'no-empty-pattern': 2, // 禁止使用空解构模式
'no-eval': 2, // 禁用 eval()
'no-ex-assign': 2, // 禁止对 catch 子句的参数重新赋值
'no-extend-native': 2, // 禁止扩展原生类型
'no-extra-bind': 2, // 禁止不必要的函数绑定
'no-extra-boolean-cast': 2, // 禁止不必要的布尔转换
'no-extra-parens': [2, 'functions'], // 禁止不必要的括号
'no-fallthrough': 2, // 禁止 case 语句落空
'no-func-assign': 2, // 禁止对 function 声明重新赋值
'no-implied-eval': 2, // 禁止使用类似 eval() 的方法
'no-inner-declarations': [2, 'functions'], // 禁止在嵌套的块中出现function 声明
'no-invalid-regexp': 2, // 禁止 RegExp 构造函数中存在无效的正则表达式字符串
'no-irregular-whitespace': 2, // 禁止不规则的空白
'no-iterator': 2, // 禁用 __iterator__ 属性
'no-label-var': 2, // 不允许标签与变量同名
'no-labels': [2, {
allowLoop: false,
allowSwitch: false
}], // 禁用标签语句
'no-lone-blocks': 2, // 禁用不必要的嵌套块
'no-multi-spaces': 2, // 禁止使用多个空格
'no-multi-str': 2, // 禁止使用多行字符串
'no-multiple-empty-lines': [2, {
max: 2
}], // 禁止出现多行空行
'no-global-assign': 2, // 禁止对原生对象或只读的全局对象进行赋值
'no-unsafe-negation': 2, // 禁止对关系运算符的左操作数使用否定操作符
'no-new-object': 2, // 禁用 Object 的构造函数
'no-new-require': 2, // 禁止调用 require 时使用 new 操作符
'no-new-wrappers': 2, // 禁止对 StringNumber 和 Boolean 使用 new 操作符
'no-obj-calls': 2, // 禁止把全局对象作为函数调用
'no-octal': 2, // 禁用八进制字面量
'no-octal-escape': 2, // 禁止在字符串中使用八进制转义序列
'no-path-concat': 2, // 禁止对 __dirname 和 __filename 进行字符串连接
'no-proto': 2, // 禁用 __proto__ 属性
'no-redeclare': 2, // 禁止多次声明同一变量
'no-regex-spaces': 2, // 禁止正则表达式字面量中出现多个空格
'no-return-assign': [2, 'except-parens'], // 禁止在 return 语句中使用赋值语句
'no-self-assign': 2, // 禁止自我赋值,禁止自身比较
'no-sequences': 2, // 禁用逗号操作符
'no-shadow-restricted-names': 2, // 禁止将标识符定义为受限的名字
'func-call-spacing': 2, // 要求或禁止在函数标识符和其调用之间有空格
'no-sparse-arrays': 2, // 禁用稀疏数组
'no-this-before-super': 2, // 禁止在构造函数中,在调用 super() 之前使用 this 或 super
'no-trailing-spaces': 2, // 禁用行尾空格
'no-undef-init': 2, // 禁止将变量初始化为 undefined
'no-unexpected-multiline': 2, // 禁止出现令人困惑的多行表达式
'no-unmodified-loop-condition': 2, // 禁用一成不变的循环条件
'no-unneeded-ternary': [2, {
defaultAssignment: false
}], // 禁止可以在有更简单的可替代的表达式时使用三元操作符
'no-unreachable': 2, // 禁止在 return、throw、continue 和 break 语句之后出现不可达代码
'no-unsafe-finally': 2, // 禁止在 finally 语句块中出现控制流语句
'no-useless-call': 2, // 禁止不必要的 .call() 和 .apply()
'no-useless-computed-key': 2, // 禁止在对象中使用不必要计算属性
'no-useless-constructor': 2, // 禁用不必要的构造函数
'no-useless-escape': 0, // 禁用不必要的转义字符
'no-whitespace-before-property': 2, // 禁止属性前有空白
'no-with': 2, // 禁用 with 语句
'one-var': [2, {
initialized: 'never'
}], // 强制函数中的变量要么一起声明要么分开声明
'operator-linebreak': [2, 'after', {
overrides: {
'?': 'before',
':': 'before'
}
}], // 强制操作符使用一致的换行符
'padded-blocks': [2, 'never'], // 要求或禁止块内填充
quotes: [2, 'single', {
avoidEscape: true,
allowTemplateLiterals: true
}], // 强制使用一致的反勾号、双引号或单引号
'semi-spacing': [2, {
before: false,
after: true
}], // 强制在块之前使用一致的空格
'space-before-blocks': [2, 'always'], // 强制在块之前使用一致的空格
'space-before-function-paren': [2, 'never'], // 强制在 function的左括号之前使用一致的空格
'space-in-parens': [2, 'never'], // 强制在圆括号内使用一致的空格
'space-infix-ops': 2, // 要求操作符周围有空格
'space-unary-ops': [2, {
words: true,
nonwords: false
}], // 强制在一元操作符前后使用一致的空格
'template-curly-spacing': [2, 'never'], // 禁止模板字符串中的嵌入表达式周围空格的使用
'use-isnan': 2, // 要求使用 isNaN() 检查 NaN
'valid-typeof': 2, // 强制 typeof 表达式与有效的字符串进行比较
'wrap-iife': [2, 'any'], // 要求 IIFE(立即执行函数) 使用括号括起来
'prefer-const': 2, // 要求使用 const 声明那些声明后不再被修改的变量
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}], // 强制在大括号中使用一致的空格
'array-bracket-spacing': [2, 'never'], // 强制数组方括号中使用一致的空格
/* 非强制 */
camelcase: [0, {
properties: 'always'
}], // 对属性名称强制使用驼峰样式
'no-array-constructor': 2, // 禁止使用 Array 构造函数创建数组
'no-caller': 2, // 禁止使用 arguments.caller 和 arguments.callee
'no-console': 'off', // 禁用console
'no-control-regex': 0// 禁止在正则表达式中使用控制字符
}
}

View File

@@ -7,54 +7,48 @@
* @LastEditTime: 2021-03-27 12:50:00
*/
/**
* 折半插入排序
* @param {Array} arr 待排序数组
* @param {int} len 数组长度
* @param arr
* @param len
*/
function binaryInsertSort(arr,len){
function binaryInsertSort(arr, len) {
// 数组长度校验【非必须】
len=arr.length===len?len:arr.length
len = arr.length === len ? len : arr.length
for(let i=1;i<len;i++){
for (let i = 1; i < len; i++) {
const temp = arr[i]
let lowIndex = 0; let highIndex = i - 1
const temp=arr[i];
let lowIndex=0,highIndex=i-1;
while(lowIndex<=highIndex){
while (lowIndex <= highIndex) {
// 注意:取整,javascript这里取整会出现空指针
const mid=parseInt((lowIndex+highIndex)/2);
const mid = parseInt((lowIndex + highIndex) / 2)
if(arr[mid]<=temp){
if (arr[mid] <= temp) {
// 右侧
lowIndex=mid+1
}else{
lowIndex = mid + 1
} else {
// 左侧
highIndex=mid-1
highIndex = mid - 1
}
}
// 元素后移
for(let j=i-1;j>highIndex;--j){
arr[j+1]=arr[j]
for (let j = i - 1; j > highIndex; --j) {
arr[j + 1] = arr[j]
}
arr[highIndex+1]=temp;
arr[highIndex + 1] = temp
}
// 返回经过折半插入排序处理的有序数组
return arr;
return arr
}
const dealArr = [5, 2, 7, 3, 18, 8, 12, 1]
console.log('插入排序前:', dealArr)
const sortResult = binaryInsertSort(dealArr, 7)
const dealArr=[5,2,7,3,18,8,12,1]
console.log('插入排序前:',dealArr)
const sortResult=binaryInsertSort(dealArr,7)
console.log('插入排序后:',sortResult)
console.log('插入排序后:', sortResult)

View File

@@ -8,23 +8,21 @@
*/
function BubbleSort (arr, len) {
function BubbleSort(arr, len) {
// 校正数组的长度
len = arr.length == len ? len : arr.length
len = arr.length === len ? len : arr.length
// 冒泡排序让数组arr有序
for (let i = 0; i < len - 1; i++) {
let isSorted = false;
let isSorted = false
// len个数组进行len-1趟一趟冒泡
for (let j = len - 1; j > i; j--) {
// 注意这里的for循环倒序是有讲究的想象一下泡泡不都是网上升的么....
if (arr[j - 1] > arr[j]) {
// 交换元素,始终让最小的元素往上走(冒泡)
const temp = arr[j - 1];
arr[j - 1] = arr[j];
const temp = arr[j - 1]
arr[j - 1] = arr[j]
arr[j] = temp
// 需要冒泡
@@ -33,7 +31,7 @@ function BubbleSort (arr, len) {
}
// 第一趟比较后,如果本身序列是有序的,就直接跳出循环
if (isSorted === false) {
break;
break
}
}
@@ -42,20 +40,19 @@ function BubbleSort (arr, len) {
/**
*
* 加减法交换元素的值
* 注意JavaScript中使用需要考虑到作用域的问题
* @param {int} a
* @param {int} b
* @param a
* @param b
*/
function swap (a, b) {
a = a + b;
b = a - b;
a = a - b;
function swap(a, b) {
a = a + b
b = a - b
a = a - b
}
const initArr = [1, 5, 8, 3, 2, 9, 16]
console.log(`冒泡排序前:${initArr}`)
const sortedArr = BubbleSort(initArr, 7);
console.log(`冒泡排序后:${sortedArr}`)
const sortedArr = BubbleSort(initArr, 7)
console.log(`冒泡排序后:${sortedArr}`)

View File

@@ -10,61 +10,58 @@
/**
* 基于分治法思想,将数组进行快速排序
* @param {Array} arr 待排序的数组
* @param {Array} arr 待排序的数组
* @param {int} low 数组低位角标 左指针
* @param {int} high 数组高位角标 右指针
* @returns
* @returns
*/
function QuickSort(arr,low,high){
function QuickSort(arr, low, high) {
// low=high 说明只有一个元素,理解为有序,不做处理
// low>high 说明左右指针已经重合,数组已经遍历完,需要跳出
if(low<high){
let pivotIndex=Partition(arr,low,high);
if (low < high) {
const pivotIndex = Partition(arr, low, high)
// 处理左侧
QuickSort(arr,low,pivotIndex-1);
QuickSort(arr, low, pivotIndex - 1)
// 处理右侧
QuickSort(arr,pivotIndex+1,high)
QuickSort(arr, pivotIndex + 1, high)
}
// 经过快排处理的数组
return arr;
return arr
}
/**
*
*
* 寻找数组中的基准pivot使得左侧元素全部小于等于pivot右侧元素全部大于等于pivot
* @param {Array} arr 分治思想处理后的数组
* @param {Array} arr 分治思想处理后的数组
* @param {int} low 数组低位角标 左指针
* @param {int} high 数组高位角标 右指针
* @returns
* @returns
*/
function Partition(arr,low,high){
function Partition(arr, low, high) {
// 假设低位指针对应数组角标元素为基准pivot
const pivot=arr[low];
while(low<high){
const pivot = arr[low]
while (low < high) {
// 从右往左直到比pivot小跳出循环
while(low<high && arr[high]>= pivot ) --high;
arr[low]=arr[high]
while (low < high && arr[high] >= pivot) --high
arr[low] = arr[high]
// 从左往右直到比pivot大跳出循环
while(low<high && arr[low]<= pivot) ++low;
arr[high]=arr[low]
while (low < high && arr[low] <= pivot) ++low
arr[high] = arr[low]
}
// 基准值移到最终的位置此时左侧小于等于pivot 右侧大于等于pivot
arr[low]=pivot
arr[low] = pivot
// 返回基准值的角标
return low;
return low
}
const initArr=[2,18,6,25,19,4,8,3,7];
const initArr = [2, 18, 6, 25, 19, 4, 8, 3, 7]
console.log(`快速排序处理前:${initArr}`)
const quickSortResult=QuickSort(initArr,0,8)
const quickSortResult = QuickSort(initArr, 0, 8)
console.log(`快速排序处理后:${quickSortResult}`)

View File

@@ -8,16 +8,14 @@
*/
/**
*
*
* 数组的希尔排序
* @param {Array} arr 待排序数组
* @param {Array} arr 待排序数组
* @param {int} len 数组长度,可校验
* @returns 返回已排序的数组,从小到大
* @returns 返回已排序的数组,从小到大
*/
function shellSort (arr, len) {
function shellSort(arr, len) {
// 校对数组长度
len = arr.length === len ? len : arr.length
@@ -25,10 +23,8 @@ function shellSort (arr, len) {
for (let increment = Math.floor(len / 2); increment >= 1; increment = Math.floor(increment / 2)) {
// 对每组数据,进行直接排序
for (let groupIndex = 0; groupIndex < increment; ++groupIndex) {
specialStraightInsertSort(arr, len, increment, groupIndex)
}
}
return arr
@@ -36,30 +32,30 @@ function shellSort (arr, len) {
/**
* 根据希尔排序的步长对分组进行直接插入排序处理
* @param {Array} arr 排序数组
* @param {Array} arr 排序数组
* @param {int} len 数组长度
* @param {int} increment 增量步长
* @param {int} groupIndex 分组,第几个分组
*/
function specialStraightInsertSort (arr, len, increment, groupIndex) {
function specialStraightInsertSort(arr, len, increment, groupIndex) {
len = arr.length === len ? len : arr.length
console.log(`数组长度:${len}----->当前步长:${increment}---->分组:${groupIndex}`)
for(let eleStartIndex=groupIndex+increment;eleStartIndex<len;eleStartIndex+=increment){
for (let eleStartIndex = groupIndex + increment; eleStartIndex < len; eleStartIndex += increment) {
// 此时eleStartIndex为直接插入排序的比较元素
// 直接插入排序中的哨兵元素【重要】
const temp=arr[eleStartIndex]
let j;
const temp = arr[eleStartIndex]
let j
// 向前比较 从小到大
for(j=eleStartIndex-increment;j>=0&&arr[j]>temp;j-=increment){
arr[j+increment]=arr[j]
for (j = eleStartIndex - increment; j >= 0 && arr[j] > temp; j -= increment) {
arr[j + increment] = arr[j]
}
arr[j+increment]=temp
arr[j + increment] = temp
}
console.log('specialStraightInsertSort处理后',arr)
console.log('specialStraightInsertSort处理后', arr)
return arr
}
@@ -69,18 +65,17 @@ function specialStraightInsertSort (arr, len, increment, groupIndex) {
* @param{Array} arr 待排序的数组
* @param{int} len 数组arr的长度可以用arr.length()计算得到
*/
function straightInsertSort (arr, len) {
function straightInsertSort(arr, len) {
// 重新确定数组长度
len = arr.length === len ? len : arr.length;
len = arr.length === len ? len : arr.length
// 从第二个元素开始循环共len-1次
for (let i = 1; i < len; i++) {
// 后面的额元素比前面的元素小,需要把前面大于哨兵元素有序序列,移动后面一位
if (arr[i] < arr[i - 1]) {
let j;
let j
// 哨兵元素
const temp = arr[i];
const temp = arr[i]
for (j = i - 1; arr[j] > temp; --j) {
// 后移
arr[j + 1] = arr[j]
@@ -93,7 +88,6 @@ function straightInsertSort (arr, len) {
}
return arr
}
@@ -105,26 +99,26 @@ console.log('插入排序后:', sortResult)
/**
* 简化的希尔排序
* @param {Array} arr
* @param {Array} arr
* @returns 返回已排序号的数组,从小到大
*/
function shellSortBetter (arr) {
var len = arr.length;
var increment = Math.floor(len / 2);
while (increment != 0) {
for (var i = increment; i < len; i++) {
var temp = arr[i]
function shellSortBetter(arr) {
const len = arr.length
let increment = Math.floor(len / 2)
while (increment !== 0) {
for (let i = increment; i < len; i++) {
const temp = arr[i]
for (var j = i - increment; j >= 0 && temp < arr[j]; j -= increment) {
arr[j + increment] = arr[j]
}
arr[j + increment] = temp;
arr[j + increment] = temp
}
increment = Math.floor(increment / 2)
}
return arr;
return arr
}
console.log('简化shellSortBetter希尔排序前', dealArr)
const sortResultBetter = shellSortBetter(dealArr)
console.log('简化shellSortBetter希尔排序后', sortResultBetter)
console.log('简化shellSortBetter希尔排序后', sortResultBetter)

View File

@@ -13,37 +13,35 @@
* @param{Array} arr 待排序的数组
* @param{int} len 数组arr的长度可以用arr.length()计算得到
*/
function straightInsertSort(arr,len){
function straightInsertSort(arr, len) {
// 重新确定数组长度
len=arr.length===len?len:arr.length;
len = arr.length === len ? len : arr.length
// 从第二个元素开始循环共len-1次
for(let i=1;i<len;i++){
for (let i = 1; i < len; i++) {
// 后面的额元素比前面的元素小,需要把前面大于哨兵元素有序序列,移动后面一位
if(arr[i]<arr[i-1]){
let j;
if (arr[i] < arr[i - 1]) {
let j
// 哨兵元素
const temp=arr[i];
for(j=i-1; arr[j]>temp;--j){
// 后移
arr[j+1]=arr[j]
const temp = arr[i]
for (j = i - 1; arr[j] > temp; --j) {
// 后移
arr[j + 1] = arr[j]
}
// 跳出循环逻辑出现arr[j] > arr[j-1]
// 哨兵即待排序的
arr[j+1]=temp
arr[j + 1] = temp
}
}
return arr
}
const dealArr=[5,2,7,3,18,8,12,1]
console.log('插入排序前:',dealArr)
const sortResult=straightInsertSort(dealArr,7)
const dealArr = [5, 2, 7, 3, 18, 8, 12, 1]
console.log('插入排序前:', dealArr)
const sortResult = straightInsertSort(dealArr, 7)
console.log('插入排序后:',sortResult)
console.log('插入排序后:', sortResult)

View File

@@ -10,78 +10,79 @@ import {sidebar} from "./sidebar";
*/
export default {
theme: hopeTheme({
locales: langConfig,
darkmode:"toggle",
// 支持全屏
fullscreen: true,
// 纯净模式s
// pure: true,
print: false, // 打印按钮
hostname:'https://408.142vip.cn',
author:{
name:'Chu Fan',
email:'fairy_408@2925.com',
url:'https://www.142vip.cn'
},
favicon:"/408_favicon.ico",
logo: "/assets/408_logo.png",
navbar: navbar,
// 导航栏布局
navbarLayout:{
start: ["Brand"],
center: ["Links"],
end: ["Language","Search","Repo", "Outlook", ]
},
sidebar: sidebar,
// sidebar: "heading",
theme: hopeTheme({
locales: langConfig,
darkmode: "toggle",
// 支持全屏
fullscreen: true,
// 纯净模式s
// pure: true,
print: false, // 打印按钮
hostname: 'https://408.142vip.cn',
author: {
name: 'Chu Fan',
email: 'fairy_408@2925.com',
url: 'https://www.142vip.cn'
},
favicon: "/408_favicon.ico",
logo: "/assets/408_logo.png",
navbar: navbar,
// 导航栏布局
navbarLayout: {
start: ["Brand"],
center: ["Links"],
end: ["Language", "Search", "Repo", "Outlook",]
},
sidebar: sidebar,
// sidebar: "heading",
// 主题布局选项
repo: "https://github.com/142vip/408CSFamily",
logoDark:"/assets/408_logo.png",
// 主题布局选项
repo: "https://github.com/142vip/408CSFamily",
logoDark: "/assets/408_logo.png",
// 博客配置
blog:{
name:'凡是过往',
avatar:'',
description:'',
intro:'',
roundAvatar:true,
timeline:"时间轴的顶部文字",
// articleInfo:"",
// sidebarDisplay:"always",
medias:{
"BiliBili": "https://space.bilibili.com/350937042?spm_id_from=333.1007.0.0"
}
},
// 博客配置
blog: {
name: '凡是过往',
avatar: '',
description: '',
intro: '',
roundAvatar: true,
timeline: "时间轴的顶部文字",
// articleInfo:"",
// sidebarDisplay:"always",
medias: {
"BiliBili": "https://space.bilibili.com/350937042?spm_id_from=333.1007.0.0"
}
},
// 设置页脚
displayFooter:true,
footer:FOOTER_HTML_INFO,
// copyright:false,
// 设置页脚
displayFooter: true,
footer: FOOTER_HTML_INFO,
// copyright:false,
// 主题色选择器
themeColor: {
blue: "#2196f3",
red: "#f26d6d",
green: "#3eaf7c",
orange: "#fb9b5f",
},
// 主题色选择器
themeColor: {
blue: "#2196f3",
red: "#f26d6d",
green: "#3eaf7c",
orange: "#fb9b5f",
},
plugins: {
copyright:false,
// 开启博客功能
// blog:true,
// 代码块
mdEnhance: {
codetabs: true,
},
copyCode: {
showInMobile:true
},
feed: {
json: true,
},
},
})
plugins: {
blog: true,
copyright: false,
// 开启博客功能
// blog:true,
// 代码块
mdEnhance: {
codetabs: true,
},
copyCode: {
showInMobile: true
},
feed: {
json: true,
},
},
})
}

View File

@@ -1,7 +1,7 @@
export const algorithmSidebar = [
{
text: '基础入门',
link: "/ds/basic_introduction",
link: '/ds/basic_introduction',
collapsible: false,
children: [{
text: '1.1 基本概念',
@@ -12,5 +12,5 @@ export const algorithmSidebar = [
}, {
text: '1.3 算法和算法评价',
link: '/ds/basic_introduction/3.algorithm_and_algorithm_evaluation.md'
}],
}]
}]
}]

View File

@@ -1,6 +1,6 @@
export const cppSidebar=[
{
text:"计算机组成原理",
children:[]
}
]
export const cppSidebar = [
{
text: '计算机组成原理',
children: []
}
]

View File

@@ -1,6 +1,6 @@
export const cnSidebar=[
{
text:"计算机网络",
children:[]
}
]
export const cnSidebar = [
{
text: '计算机网络',
children: []
}
]

View File

@@ -1,7 +1,7 @@
export const dsSidebar = [
{
text: '基础入门',
prefix: "basic-introduction",
prefix: 'basic-introduction',
collapsible: false,
children: [
{
@@ -16,12 +16,12 @@ export const dsSidebar = [
text: '1.3 算法和算法评价',
link: '3.algorithm_and_algorithm_evaluation.md'
}
],
]
},
{
text: '线性表',
collapsible: false,
prefix: "linear-table",
prefix: 'linear-table',
children: [
{
text: '2.1 基础概念和操作',
@@ -58,11 +58,11 @@ export const dsSidebar = [
text: '2.9 零碎知识补充',
link: '9.piecemeal_knowledge_supplement.md'
}
],
]
},
{
text: "栈和队列",
prefix: "栈和队列",
text: '栈和队列',
prefix: '栈和队列',
collapsible: false,
children: [
{
@@ -98,4 +98,4 @@ export const dsSidebar = [
}
]
}
]
]

View File

@@ -1,23 +1,23 @@
export const noteMapSidebar=[{
text: '考研相关',
children: [{
text: '测试',
link: '/333'
}]
export const noteMapSidebar = [{
text: '考研相关',
children: [{
text: '测试',
link: '/333'
}]
}, {
text: "思维导图",
children: [{
text: '数据结构',
link: 'ds-map.md'
}, {
text: '操作系统',
link: 'os-map.md'
}, {
text: '计算机组成原理',
link: 'ccp-map.md'
}, {
text: '计算机网络',
link: 'cn-map.md'
}]
}]
text: '思维导图',
children: [{
text: '数据结构',
link: 'ds-map.md'
}, {
text: '操作系统',
link: 'os-map.md'
}, {
text: '计算机组成原理',
link: 'ccp-map.md'
}, {
text: '计算机网络',
link: 'cn-map.md'
}]
}]

View File

@@ -1,6 +1,6 @@
export const osSidebar = [
{
text: "操作系统",
children: []
}
]
{
text: '操作系统',
children: []
}
]

View File

@@ -1,44 +0,0 @@
/*
* @Description: 折半插入算法【伪代码】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-04-15 18:27:59
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-27 12:19:13
*/
void BinaryInsertSort(ElemType Arr[],int n){
int i,j,lowIndex,heightIndex,midIndex;
for(i=2;j<=n;i++){
// 将待排序的元素暂存在Arr[0]上
Arr[0]=Arr[i];
lowIndex=1; // 左侧子表 折半查找起始位置
heightIndex=i-1; // 左侧子表 折半查找结束位置
while(lowIndex<=heightIndex){
// 左侧有序子表的中间位置角标
midIndex=(lowIndex+hightIndex)/2;
if(Arr[midIndex].key>Arr[0].key){
// 小于中间元素,插入位置在子表左侧
hightIndex=mid-1
}else{
// 大于或者等于中间元素,插入位置在子表右侧
lowIndex=midIndex+1;
}
}
// 跳出循环需要lowIndex>hightIndex说明待插入位置的角标在hightIndex之后为 hightIndex+1,此时需要将hightIndexi之间的所有元素后移
for(j=i-1;j>heightIndex;--j){
Arr[j+1]=Arr[j]
}
// 后移完成后将元素Arr[0]赋值到位置hightIndex+1
Arr[heightIndex+1]=Arr[0]
}
}

View File

@@ -1,60 +0,0 @@
/*
* @Description: 折半插入排序【JavaScript版本】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-03-27 12:35:17
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-27 12:50:00
*/
/**
* 折半插入排序
* @param {Array} arr 待排序数组
* @param {int} len 数组长度
*/
function binaryInsertSort(arr,len){
// 数组长度校验【非必须】
len=arr.length===len?len:arr.length
for(let i=1;i<len;i++){
const temp=arr[i];
let lowIndex=0,highIndex=i-1;
while(lowIndex<=highIndex){
// 注意:取整,javascript这里取整会出现空指针
const mid=parseInt((lowIndex+highIndex)/2);
if(arr[mid]<=temp){
// 右侧
lowIndex=mid+1
}else{
// 左侧
highIndex=mid-1
}
}
// 元素后移
for(let j=i-1;j>highIndex;--j){
arr[j+1]=arr[j]
}
arr[highIndex+1]=temp;
}
// 返回经过折半插入排序处理的有序数组
return arr;
}
const dealArr=[5,2,7,3,18,8,12,1]
console.log('插入排序前:',dealArr)
const sortResult=binaryInsertSort(dealArr,7)
console.log('插入排序后:',sortResult)

View File

@@ -1,59 +0,0 @@
/*
* @Description: 冒泡排序
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-03-31 08:24:18
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-06 07:26:15
*/
void BubbleSwapSort(ElemType A[], int n){
for(i=0;i<n-1;i++){
// 当前趟次冒泡是否发生了元素交换初始化为false
bool flag=false;
for(j=n-1;j>i;j--){
if(A[j-1].key>A[j].key){
// 将两个元素A[j-1]、A[j]进行交换,有多种方法
swap(A[j-1],A[j])
// 确认已发生交换
flag=true
}
}
// 本趟遍历后没有发生交换,说明表已经有序
if(flag==false){
return ;
}
}
}
/**
* 加减法实现两个元素值互换
*
*/
void swap(int a, int b){
// 此时a为两值的和
a=a+b;
// 此时b的值为a
b=a-b
// 如何实现让a的值为b呢此时a的值为b
a=a-b;
}
/**
* 临时变量实现两个元素值的互换
*
*/
void swap(int a,int b){
int temp;
temp=a;
a=b;
b=temp
}

View File

@@ -1,61 +0,0 @@
/*
* @Description: 冒泡排序【JavaScript版本】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-06 07:26:59
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-06 08:01:19
*/
function BubbleSort (arr, len) {
// 校正数组的长度
len = arr.length == len ? len : arr.length
// 冒泡排序让数组arr有序
for (let i = 0; i < len - 1; i++) {
let isSorted = false;
// len个数组进行len-1趟一趟冒泡
for (let j = len - 1; j > i; j--) {
// 注意这里的for循环倒序是有讲究的想象一下泡泡不都是网上升的么....
if (arr[j - 1] > arr[j]) {
// 交换元素,始终让最小的元素往上走(冒泡)
const temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp
// 需要冒泡
isSorted = true
}
}
// 第一趟比较后,如果本身序列是有序的,就直接跳出循环
if (isSorted === false) {
break;
}
}
return arr
}
/**
*
* 加减法交换元素的值
* 注意JavaScript中使用需要考虑到作用域的问题
* @param {int} a
* @param {int} b
*/
function swap (a, b) {
a = a + b;
b = a - b;
a = a - b;
}
const initArr = [1, 5, 8, 3, 2, 9, 16]
console.log(`冒泡排序前:${initArr}`)
const sortedArr = BubbleSort(initArr, 7);
console.log(`冒泡排序后:${sortedArr}`)

View File

@@ -1,155 +0,0 @@
/*
* @Description: 单链表
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-03-04 23:38:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-05 21:30:58
*/
/*
* @Description: 单链表头插法
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-04 23:38:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2020-03-04 23:39:16
*/
LinkList CreateListWithStartNode(LinkList &L){
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode)); // 创建头结点L
L->next=NULL; // 初始化空链表
// 控制台输入值
scanf("%d",&x);
// 输入9999 表示结束
while(x!==9999){
// 开辟新结点存储空间
s=(LNode*)malloc(sizeof(LNode));
// 结点数据域赋值
s->data=x;
// 修改指针新结点插入表中【注意L->next为头结点的指针域】
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
// 返回单链表
return L;
}
/*
* @Description: 单链表尾插法
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-04 23:38:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2020-03-04 23:39:16
*/
LinkList CreateListWithEndNode(LinkList &L){
int x; // 输入结点值
L=(LinkList)malloc(sizeof(LNode));
LNode *s; // 新结点s
LNode *r=L; // r为尾指针
// 控制台输入值
scanf("%d",&x);
while(x!==9999){
// 开辟新结点存储空间
s=(LNode *)malloc(sizeof(LNode));
// 新结点s的数据域赋值为x
s->data=x;
// 单链表L的尾指针指向新的结点s
r->next=s;
// 指针r指向新的表尾结点
r=s;
scanf("%d",&x);
}
// 表尾指针置空【重要】
r->next=NULL;
// 返回单链表
return L;
}
/*
* @Description: 单链表按序号查找
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-04 23:38:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2020-03-04 23:39:16
*/
LNode *GetElem(LinkList L,int i){
int j=1; // 查询计数初始为1
LNode *p=L->next; // 单链表头结点指针赋值给指针p
// 第0个元素则指向头结点返回头结点
if(i==0){
// 头结点包含数据域和指针域
return L;
}
// 不等于0却小于1则i为负数无效直接返回NULL查询结果空
if(i<1){
return NULL;
}
// p存在且计数没有走到初始i的位置
while(p&&j<i){
// 指针后移
p=p->next;
// 计数标记+1
j++;
}
// 注意: 当p不存在时 跳出循环p=NULL; 当p存在但是j大于等于i跳出循环返回查找的结果返回p
// 从跳出循环上来分析p要么存在即找到的结点元素要么为空即NULL
// 跳出循环返回第i个结点的指针
return p;
}
/*
* @Description: 单链表按值查找
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-04 23:38:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2020-03-04 23:39:16
*/
LNode *LocateElem(LinkList L,ElemType e){
// 指针【哨兵】
LNode *p=L->next;
// 从第1个结点开始查找数据域(data)为e的结点
while(p!=NULL&&p->data!=e){
// 无法匹配,指针后移
p=p->next;
}
// 注意p为NULL的时候说明单链表已经遍历的尾结点了跳出循环没有找到目标结点
// 查找到第1个匹配的结点跳出循环返回结点指针
return p;
//
}

View File

@@ -1,91 +0,0 @@
/*
* @Description: 链栈的相关操作
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-01-15 9:19:56
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-13 12:27:36
*/
// 链栈类型定义【基础】
typedef struct LinkNode{
ElemType data; // 栈元素结点数据域
struct LinkNode *next; // 栈元素结点指针域
} *LinkStack;
// 更为详细的定义
typedef struct StackNode
{
int data;//结点数据域
struct StackNode* next;//结点指针域
}StackNode,* Linktop;
//链栈的数据结构
typedef struct LinkStack
{
Linktop top; //栈顶结点,定义了一个指向上个结构体的指针
int count;//元素个数
}LinkStack;
/*
* @Description: 基于单链表链栈的进栈操作
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-04 07:36:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2020-03-04 11:39:16
*/
bool linkStackPushNode(LinkStack* linkStack,int e){
// 判断链栈是否存在
if (!linkStack){
//链栈不存在无法进栈操作返回false
return false;
}
// 开辟栈结点元素内存控件
StackNode* node = (StackNode*)malloc(sizeof(StackNode));
// 新结点指针域指向链表,即栈顶指针位置,元素加入链表
node->next = linkStack->top;
// 新结点数据域赋值
node->data = e;
// 元素进栈,移动栈顶指针,指向新入栈的元素
linkStack->top = node;
// 链栈元素总数+1
linkStack->count++;
//链栈入栈成功返回true
return true;
}
/*
* @Description: 基于单链表链栈的出栈操作
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-04 23:38:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2020-03-04 23:39:16
*/
bool linkStackPopNode(LinkStack* linkStack,int *e){
// 判断链栈是否存在及是否为空
if (!linkStack || linkStack->count==0){
//出栈失败返回false
return false;
}
// 获取栈顶元素结点
StackNode* node = stack->top;
// 结点元素数据域赋值给变量e
*e = linkStack->data;
// 移动栈顶指向,栈顶指针指向待出栈结点的后继结点
linkStack->top = node->next;
// 变量e已被赋值释放链栈出栈元素的内存控件
free(node);
// 链栈元素个数-1
linkStack->count--;
// 出栈成功返回true.
return true;
}

View File

@@ -1,56 +0,0 @@
/*
* @Description: 循环队列操作
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2019-09-27 14:17:28
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-18 23:52:10
*/
// 队列最大存储元素个数
#define MaxSize 50
// 结构体定义
typedef struct {
// 存放队列元素
ElemType data[MaxSize];
// 队头指针和队尾指针
int front,rear;
} SqQueue;
// 入队算法
// 尾插法Q.data[Q.rear]=x;Q.rear=(Q.rear+1)%Maxsize;Q.tag=1
// 队空条件Q.front== Q.rear且Q.tag==0
int EnLoopQueue(SqQueue &Q, ElemType x){
if(Q.front==Q.rear&&Q.tag==1){
return 0;
}
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;
Q.tag=1;
return 1;
}
// 出队算法
// 头结点删除x=Q.data[Q.front];Q.front=(Q.front +1)%Maxsize;Q.tag=0
// 队满条件Q.front == Q.rear且Q.tag=1
// 注意:当删除之后链表为空时,还需增加一步,将尾指针指向头结点
int DeLoopQueue(SqQueue &Q, ElemType &x){
if (Q.front==Q.rear&&Q.tag==0){
return 0;
}
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
Q.tag=0;
return 1;
}

View File

@@ -1,47 +0,0 @@
/*
* @Description: 快速排序【伪代码】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-23 08:23:20
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-08 21:51:28
*/
void QuickSort(ElemType A[] , int low , int high){
// low > high 表角标越界low=high 子表只有一个元素,不需要进行快排,已经有序
if(low<high){
// 获取pivot基准将当前待排序表分成左右两个子表
int pivotKey = Partition(A,low,high)
// 对左边序列进行快排
QuickSort(A,low,pivotKey-1)
// 对右边序列进行快排
QuickSort(A,pivotKey+1,high)
}
return A
}
int Partition(ElemType A ,int low , int high){
ElemType pivot=A[low];
while(low<high){
while(low<high && A[high]>=pivot) --high
A[low]=A[high] // 比pivot小的都移到左表 注意--high 从后往前遍历
while(low<high && A[low]<=pivot ) ++low
A[high]=A[low] // 比pivot大的都移到右表注意++low 从前往后遍历
}
// 此时low==high||low>high 跳出循环后即找到能将当前表一分为二的pivotKey值
A[low]=pivot
// 基准元素pivot对应最终的位置角标
return low
}

View File

@@ -1,70 +0,0 @@
/*
* @Description: 快速排序【JavaScript版本】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-08 08:20:35
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-08 21:50:12
*/
/**
* 基于分治法思想,将数组进行快速排序
* @param {Array} arr 待排序的数组
* @param {int} low 数组低位角标 左指针
* @param {int} high 数组高位角标 右指针
* @returns
*/
function QuickSort(arr,low,high){
// low=high 说明只有一个元素,理解为有序,不做处理
// low>high 说明左右指针已经重合,数组已经遍历完,需要跳出
if(low<high){
let pivotIndex=Partition(arr,low,high);
// 处理左侧
QuickSort(arr,low,pivotIndex-1);
// 处理右侧
QuickSort(arr,pivotIndex+1,high)
}
// 经过快排处理的数组
return arr;
}
/**
*
* 寻找数组中的基准pivot使得左侧元素全部小于等于pivot右侧元素全部大于等于pivot
* @param {Array} arr 分治思想处理后的数组
* @param {int} low 数组低位角标 左指针
* @param {int} high 数组高位角标 右指针
* @returns
*/
function Partition(arr,low,high){
// 假设低位指针对应数组角标元素为基准pivot
const pivot=arr[low];
while(low<high){
// 从右往左直到比pivot小跳出循环
while(low<high && arr[high]>= pivot ) --high;
arr[low]=arr[high]
// 从左往右直到比pivot大跳出循环
while(low<high && arr[low]<= pivot) ++low;
arr[high]=arr[low]
}
// 基准值移到最终的位置此时左侧小于等于pivot 右侧大于等于pivot
arr[low]=pivot
// 返回基准值的角标
return low;
}
const initArr=[2,18,6,25,19,4,8,3,7];
console.log(`快速排序处理前:${initArr}`)
const quickSortResult=QuickSort(initArr,0,8)
console.log(`快速排序处理后:${quickSortResult}`)

View File

@@ -1,55 +0,0 @@
/*
* @Description: 希尔排序【伪代码】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-13 13:05:22
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-27 17:03:41
*/
void ShellSort(ElemType Arr[] , int n){
// k是增量
for(k=n/2;k>=1;k=k/2){
// 增量子表进行直接插入排序
for(i=k+1;i<=n;++i){
if(Arr[i].key<Arr[i-k].key){
// 元素暂存
Arr[0]=Arr[i];
for(j=i-k;j>0&&Arr[0].key<Arr[j].key;j-=k){
// 记录后移,查找插入的位置
Arr[j+k]=Arr[j]
}
// 插入
Arr[j+k]=Arr[0]
}
}
}
}
void ShellSortEnhance(ElemType Arr[] , int n){
// 采用k=n/2 幂函数 确认希尔排序的步长
for(k=n/2;k>=1;n/=2){
// // 步长为k则对应分为k个组分别对其进行 直接插入排序
for(i=1,i<=k;i++){
// 第一步: 对应组的元素找出来,组成新的待排序的数列
// 第二步: 对待排序数列进行 直接插入排序
specialStraightInsertSort(ElemType Arr[], int n , int k , int i)
}
}
// 返回
return Arr;
}

View File

@@ -1,130 +0,0 @@
/*
* @Description: 希尔排序
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-02-21 08:07:13
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-28 11:37:29
*/
/**
*
* 数组的希尔排序
* @param {Array} arr 待排序数组
* @param {int} len 数组长度,可校验
* @returns 返回已排序的数组,从小到大
*/
function shellSort (arr, len) {
// 校对数组长度
len = arr.length === len ? len : arr.length
// 注意处理浮点【向上取整】 防止空指针
for (let increment = Math.floor(len / 2); increment >= 1; increment = Math.floor(increment / 2)) {
// 对每组数据,进行直接排序
for (let groupIndex = 0; groupIndex < increment; ++groupIndex) {
specialStraightInsertSort(arr, len, increment, groupIndex)
}
}
return arr
}
/**
* 根据希尔排序的步长对分组进行直接插入排序处理
* @param {Array} arr 排序数组
* @param {int} len 数组长度
* @param {int} increment 增量步长
* @param {int} groupIndex 分组,第几个分组
*/
function specialStraightInsertSort (arr, len, increment, groupIndex) {
len = arr.length === len ? len : arr.length
console.log(`数组长度:${len}----->当前步长:${increment}---->分组:${groupIndex}`)
for(let eleStartIndex=groupIndex+increment;eleStartIndex<len;eleStartIndex+=increment){
// 此时eleStartIndex为直接插入排序的比较元素
// 直接插入排序中的哨兵元素【重要】
const temp=arr[eleStartIndex]
let j;
// 向前比较 从小到大
for(j=eleStartIndex-increment;j>=0&&arr[j]>temp;j-=increment){
arr[j+increment]=arr[j]
}
arr[j+increment]=temp
}
console.log('specialStraightInsertSort处理后',arr)
return arr
}
/**
* 插入排序
* @param{Array} arr 待排序的数组
* @param{int} len 数组arr的长度可以用arr.length()计算得到
*/
function straightInsertSort (arr, len) {
// 重新确定数组长度
len = arr.length === len ? len : arr.length;
// 从第二个元素开始循环共len-1次
for (let i = 1; i < len; i++) {
// 后面的额元素比前面的元素小,需要把前面大于哨兵元素有序序列,移动后面一位
if (arr[i] < arr[i - 1]) {
let j;
// 哨兵元素
const temp = arr[i];
for (j = i - 1; arr[j] > temp; --j) {
// 后移
arr[j + 1] = arr[j]
}
// 跳出循环逻辑出现arr[j] > arr[j-1]
// 哨兵即待排序的
arr[j + 1] = temp
}
}
return arr
}
const dealArr = [5, 8, 2, 16, 3, 9, 1]
console.log('插入排序前:', dealArr)
const sortResult = shellSort(dealArr, 7)
console.log('插入排序后:', sortResult)
/**
* 简化的希尔排序
* @param {Array} arr
* @returns 返回已排序号的数组,从小到大
*/
function shellSortBetter (arr) {
var len = arr.length;
var increment = Math.floor(len / 2);
while (increment != 0) {
for (var i = increment; i < len; i++) {
var temp = arr[i]
for (var j = i - increment; j >= 0 && temp < arr[j]; j -= increment) {
arr[j + increment] = arr[j]
}
arr[j + increment] = temp;
}
increment = Math.floor(increment / 2)
}
return arr;
}
console.log('简化shellSortBetter希尔排序前', dealArr)
const sortResultBetter = shellSortBetter(dealArr)
console.log('简化shellSortBetter希尔排序后', sortResultBetter)

View File

@@ -1,80 +0,0 @@
/*
* @Description: 顺序表的基础操作
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-02-23 07:48:26
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-02-23 07:48:26
*/
// 基础结构体
define MaxSize 50;
typedef struct{
ElemType data[MaxSize]; // ElemType 代表元素类型 int、string.....
int length;
}SqList
bool ListInsert(SqList &L, int i, ElemType e){
// i非法 i=1 表头 i=L.length+1 表尾巴
if(i<1||i>L.length+1){
return false;
}
// 存储空间满,无法插入
if(L.length >= MaxSize){
return false;
}
// 遍历,将位置元素往后移动,注意从后往前循环,避免值被覆盖
for(int j=L.length; j>=i;j--){
L.data[j]=L.data[j-1];
}
// 此时表L中的第i个元素和第i+1元素素值一样将新元素存入i位置即可
// 第i个元素对应的位置角标为i-1
L.data[i-1]=e;
// 表长度加1
L.length++;
// 返回插入成功
return true;
}
bool ListDelete(SqList &L, int i, ElemType &e){
// i非法 i=1 表头 i=L.length+1 表尾巴
if(i<1||i>L.length+1){
return false;
}
// 存储空间满,无法插入
if(L.length >= MaxSize){
return false;
}
// 引用变量e赋值
e=L.data[i-1]
// 遍历第i个元素后面的往前移动
for(int j=i; j<=L.length;j++){
// 从第i个元素开始角标从i-1开始
L.data[j-1]=L.data[j];
}
// 此时表L中的表尾元素和倒数第二个元素值一样将表的长度-1
// 表长度减1
L.length--;
// 返回删除成功
return true;
}

View File

@@ -1,81 +0,0 @@
/*
* @Description: 顺序栈的相关操作
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2020-03-07 11:15:04
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-13 12:30:18
*/
// 定义栈中元素的最大个数
# define MaxSize 50
// 结构体定义
typedef struct{
ElemType data[MaxSize]; // 存放栈中元素
int top; // 栈顶指针
}SqStack;
// 初始化
void InitStack(&S){
// 栈顶指针-1
s.top=-1;
}
// 栈空判断
bool StackEmpty(S){
if(S.top==-1){
// 栈空
return true;
}else{
// 栈非空
return false;
}
}
// 进栈
bool Push(SqStack &S,ElemType x){
if(S.top==MaxSize-1){
// 栈满返回false元素无法进行进栈操作
return false;
}else{
// 可进栈,栈顶指针+1再元素入栈
S.data[++S.top]=x;
// 入栈成功
return true;
}
}
// 出栈
bool Pop(SqStack &S,ElemType &x){
if(S.top==-1){
// 栈空无栈顶元素可出栈返回false
return false;
}else{
// 栈非空,先元素出栈,再进行指针-1
x=S.data[S.top--];
// 出栈成功返回true
return true;
}
}
// 读(获取)栈顶元素
bool GetTop(SqStack S,ElemType &x){
if(S.top==-1){
// 栈空,无栈顶元素,返回false
return false;
}else{
// 通过栈顶指针获取栈顶元素赋值给变量x
x=S.data[S.top];
// 读取栈顶元素成功返回true
return true;
}
}

View File

@@ -1,26 +0,0 @@
/*
* @Description: 直接插入排序【伪代码】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-03-25 08:07:23
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-26 07:29:00
*/
void straightInsertSort(ElemType A[], int n){
int i,j;
// 依次将前面的第2到第n个元素插入到前面的有序序列
for(i=2;i<=n;i++){
if(A[i].key< A[i-1].key){
// 哨兵元素
A[0]=A[i];
// 循环向后挪动
for(j=i-1;A[0].key<A[j].key;--j){
A[j+1]=A[j]
}
// 哨兵元素插入注意这里为j+1因为--j等循环完先递减再使用比预想靠后
A[j+1]=A[0]
}
}
}

View File

@@ -1,49 +0,0 @@
/*
* @Description: 直接插入排序【JavaScript版本】
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-03-25 08:14:07
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-03-26 07:29:47
*/
/**
* 插入排序
* @param{Array} arr 待排序的数组
* @param{int} len 数组arr的长度可以用arr.length()计算得到
*/
function straightInsertSort(arr,len){
// 重新确定数组长度
len=arr.length===len?len:arr.length;
// 从第二个元素开始循环共len-1次
for(let i=1;i<len;i++){
// 后面的额元素比前面的元素小,需要把前面大于哨兵元素有序序列,移动后面一位
if(arr[i]<arr[i-1]){
let j;
// 哨兵元素
const temp=arr[i];
for(j=i-1; arr[j]>temp;--j){
// 后移
arr[j+1]=arr[j]
}
// 跳出循环逻辑出现arr[j] > arr[j-1]
// 哨兵即待排序的
arr[j+1]=temp
}
}
return arr
}
const dealArr=[5,2,7,3,18,8,12,1]
console.log('插入排序前:',dealArr)
const sortResult=straightInsertSort(dealArr,7)
console.log('插入排序后:',sortResult)

View File

@@ -1,44 +0,0 @@
// 判断数据类型
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;
}

View File

@@ -1,105 +0,0 @@
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
}
// [leftright]
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
};

View File

@@ -1,44 +0,0 @@
//
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))

View File

@@ -1,61 +0,0 @@
/**
* 非递归实现快速排序
* @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))

View File

@@ -1,24 +0,0 @@
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)

View File

@@ -1,56 +0,0 @@
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
};

View File

@@ -1,22 +0,0 @@
'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');

View File

@@ -1,43 +0,0 @@
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"));

View File

@@ -1,40 +0,0 @@
/**
*
* @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))

View File

@@ -1,72 +0,0 @@
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
};

View File

@@ -1,25 +0,0 @@
/**
*
* @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]
]))

View File

@@ -1,42 +0,0 @@
/**
* ++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)

View File

@@ -1,24 +0,0 @@
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)

View File

@@ -1,91 +0,0 @@
/**
* 给出一个整数数组, 请在数组中找出两个加起来等于目标值的数,
你给出的函数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'))

View File

@@ -1,102 +0,0 @@
<!--
* @Description: 关于前端算法刷题
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-29 07:33:14
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-30 23:19:21
-->
## 前端算法刷题
> 相比后端涉及到的算法,前端的算法较为基础,常常是用来解决某个场景的问题
- 刷题平台: [牛客网](https://www.nowcoder.com/ta/front-end)
- 语言版本JavaScript
### 入门
- dom 节点查找
- 根据包名,在指定空间中创建对象
- 斐波那契数列
- 字符串字符统计
- 数组求和
- 删除数组最后一个元素
- 添加元素
- 删除数组第一个元素
- 数组合并
- 计数
- 求二次方
- 查找元素位置
- 避免全局变量
- 正确的使用
- 完全等同
- 函数传参
- 函数的上下文
- 二次封装函数
- 使用 arguments
- 柯里化
- 或运算
- 且运算
- 二进制转换
- 乘法
- 改变上下文
- 批量改变对象的属性
- 判断是否包含数字
- 判断是否以元音字母结尾
### 简单
- 获取字符串的长度
- 段落标识
- 查找数组元素位置
- 移除数组中的元素
- 添加元素
- 添加元素
- 正确的函数定义
- 返回函数
- 使用 apply 调用函数
- 二次封装函数
- 二进制转换
- 二进制转换
- 属性遍历
- 检查重复字符串
- 获取指定字符串
- 判断是否符合指定格式
### 中等
- 修改 this 指向
- 时间格式化输出
- 邮箱字符串判断
- 颜色字符串转换
- 将字符串转换为驼峰格式
- 加粗文字
- 移除数组中的元素
- 查找重复元素
- 计时器
- 流程控制
- 使用闭包
- 判断是否符合 USD 格式
### 较难
- 获取 url 参数
- 数组去重
- 设置文字颜色
- 模块
### 困难
在牛客网题库——前端大挑战中暂时没有标记为`困难`的题目个人觉得按照常用的场景把前面的几个分类刷完就ok了没事多刷刷呗

View File

@@ -1,46 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 07:50:21
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-23 22:05:34
*/
function add(){
console.log(arguments);
var args=Array.prototype.slice.call(arguments)
console.log(args)
var _add=function(){
console.log('add',arguments)
args.push(...arguments);
// 返回函数
return _add;
}
console.log(args)
// 对参数数组做求和处理
_add.toString=function(){
// 设置sum的起始值为0
return args.reduce((sum,item)=>{
console.log(sum,item)
return sum+item;
})
}
// 返回函数
return _add
}
let str=add(1,6)(2)(3)
console.log(str)
// console.log(String(add(1,6)(2)(3)) )
// console.log(add(1)(2)(3))
// console.log(add(1)(2,3,4))

View File

@@ -1,31 +0,0 @@
/*
* @Description: 字符串中字符出现频率计数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-14 10:21:39
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-14 10:22:19
*/
function count(str) {
// 转换为数组后去重
const originArr=str.split('')
const arr=[...new Set(originArr)];
let result={};
for(let index=0;index<arr.length;index++){
const value=arr[index];
let count=0;
if(value!==' '){
originArr.map(item=>{
if(item===value){
count++
}
})
// 对象计数
result[value]=count
}
}
return result;
}

View File

@@ -1,30 +0,0 @@
/*
* @Description: 找出数组 arr 中重复出现过的元素
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-14 10:22:51
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-14 10:22:51
*/
// 找出数组 arr 中重复出现过的元素
function duplicates(arr) {
const sortArr=arr.sort();
let result=new Array()
const len=sortArr.length;
for(let index=0;index<len-1;index++){
if(sortArr[index]===sortArr[index++]){
result.push(sortArr[index])
}
}
// 去重
return [...new Set(result)];
}
console.log(duplicates([1, 2, 4, 4, 3, 3, 1, 5, 3]))

View File

@@ -1,46 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-21 07:15:31
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-21 12:01:57
*/
function isUSD (str) {
if (!str.startsWith('$')) {
return false;
}
if (str.indexOf('.')) {
// 小数
let arr = str.split('.');
if (arr[1].length !== 2) {
return false;
};
let strArr = arr[0].split(',');
for (let index = 0; index < strArr.length; index++) {
if (strArr[index].length !== 3) {
return false;
}
}
return true;
}
let strArr = str.split(',');
for (let index = 0; index < strArr.length; index++) {
if (strArr[index].length !== 3) {
return false;
}
}
return true;
}
console.log(isUSD('$20,933,209.93'))

View File

@@ -1,44 +0,0 @@
/*
* @Description: 【FED19】 移除数组中的元素
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-13 22:47:38
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-14 10:23:19
*/
/**
* 移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回
* @param {*} arr
* @param {*} item
* @returns
*/
function removeWithoutCopy(arr, item) {
// const result= arr.filter(value=>value!==item)
// // 输出
// return result;
// 每次都和arr中的首个元素去比较
const len=arr.length;
for(let index=0;index<len;index++){
if(arr[0]!==item){
arr.push(arr[0])
}
// 删除第一个
arr.shift()
}
return arr;
}
const test = [1, 2, 2, 3, 4, 2, 2]
console.log(removeWithoutCopy(test,2))

View File

@@ -1,44 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 22:49:55
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-23 22:54:42
*/
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
};

View File

@@ -1,17 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 22:56:17
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-23 22:57:59
*/
// 明确一点,栈是后进先出,或者说是先进后出
function IsPopOrder (pushV, popV) {
// write code here
}
module.exports = {
IsPopOrder: IsPopOrder
};

View File

@@ -1,25 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 23:02:58
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-23 23:03:10
*/
function Permutation (str) {
// write code here
let result=[];
let i=0;
while(i<str.length){
let j=0
while(j<=i){
result.push(str[j])
}
}
}
module.exports = {
Permutation: Permutation
};

View File

@@ -1,69 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 23:11:40
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-24 17:52:06
*/
function FindGreatestSumOfSubArray01 (array) {
// 标记指针
let index = 0;
// 子串的累计结果
let sum = 0;
// 子串的累加和最大值,当标记位从
let max = array[index];
// 循环
while (index < array.length) {
sum += array[index];
max = sum > max ? sum : max;
// 注意,重新计数
sum = sum > 0 ? sum : 0
index++
}
return max;
}
function FindGreatestSumOfSubArray (array) {
// write code here
// 首位指针
let i = 0;
// 从第一个元素开始,假设最大
let max = array[0]
let sum = 0;
while (i < array.length) {
// 替换
// 和下一个元素求和
sum += array[i];
// 获取最大值
max = sum > max ? sum : max;
// 小于sum值则说明累加和变小了下一个模块重新计数
sum = sum < 0 ? 0 : sum;
// 标记指针后移
i++
}
return max;
}
console.log(FindGreatestSumOfSubArray01([1, -2, 3, 10, -4, 7, 2, -5]))
console.log(FindGreatestSumOfSubArray([-2, -8, -1, -5, -9]))
module.exports = {
FindGreatestSumOfSubArray: FindGreatestSumOfSubArray
};

View File

@@ -1,95 +0,0 @@
/*
* @Description: 除了先排序,也是利用对象进行标记处理的;
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-24 18:19:20
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-24 18:52:58
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @return int整型一维数组
*/
function FindNumsAppearOnce (array) {
// write code here
// 数组中元素要么出现一次,要么出现两次,可以先对元素进行排序 Math.sort((a,b)=>a-b) 从小到大 有点偷懒的样子
array=quickSort(array, 0, array.length - 1);
// 此时的 数组已经进过排序
let result=[]
// 出现一次的元素,在中间
for(let index=1;index<array.length-1;index++){
if(array[index-1]!==array[index]&&array[index]!==array[index+1]){
result.push(array[index])
}
}
// 假设在开头
if(array[0]!==array[1]){
result.push(array[0])
}
// 假设在结尾
if(array[array.length-1]!==array[array.length-2]){
result.push(array[array.length-1])
}
// 过滤掉只出现一次的元素, 进行排序从小到大;
return result.sort((a,b)=>a-b)
}
function quickSort (arr, left, right) {
if (left < right) {
const pivot = partition(arr, left, right);
// 左侧
quickSort(arr, left, pivot - 1)
// 右侧
quickSort(arr, pivot + 1, right)
}
return arr;
}
function partition (arr, left, right) {
let pivot = arr[left];
while (left < right) {
while (left < right && pivot <= arr[right]) --right;
arr[left] = arr[right];
while (left < right && pivot >= arr[left]) ++left;
arr[right] = arr[left]
}
arr[left] = pivot;
return left
}
console.log(FindNumsAppearOnce([1, 4, 1, 6, 7]))
module.exports = {
FindNumsAppearOnce: FindNumsAppearOnce
};

View File

@@ -1,23 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-24 11:51:20
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-24 12:02:23
*/
function multiply (array) {
let result = [];
for (let index = 0; index < array.length; index++) {
// result.push(array.slice(0, index).reduce((res, item) => res * item, 1) * array.slice(index + 1).reduce((res, item) => res * item, 1))
result.push([...array.slice(0, index), ...array.slice(index + 1)].reduce((res, item) => {
return res * item;
},1)) // 给res的初始值为1
}
return result;
}
console.log(multiply([1, 2, 3, 4, 5]))

View File

@@ -1,44 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-24 17:53:01
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-24 18:14:24
*/
function minNumberInRotateArray (rotateArray) {
// write code here
const len=rotateArray.length;
if (rotateArray.length < 0) {
return 0
}
// 重新整理思路 旋转数组: 非递减 基于分治的思路,对数组进行切割;
let index=0;
// 直接二分查找
while(index<len){
}
}
function isSortArr(arr){
for(let index=0;index<arr.length-1;index++){
if(arr[index]>arr[index+1]){
return true;;
}
}
return false;
}
console.log(minNumberInRotateArray([3,4,5,1,2]))
module.exports = {
minNumberInRotateArray: minNumberInRotateArray
};

View File

@@ -1,48 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 22:14:37
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-23 22:23:46
*/
//
/**
* Math.power(base,exponent)
* 保证base和exponent不同时为0。不得使用库函数同时不需要考虑大数问题也不用考虑小数点后面0的位数。
* @param {double} base
* @param {int} exponent
*/
function Power (base, exponent) {
// write code here
let result = 1;
if (exponent > 0) {
// 正数
while (exponent > 0) {
result *= base;
exponent--
}
return result;
} else if (exponent < 0) {
// 负数 取反 绝对值 abs
// let abs=Math.abs(exponent)
let abs = -exponent;
while (abs > 0) {
result *= base;
abx--
}
return 1 / result;
} else {
// 0 返回1
return result;
}
}
console.log(Power(2.10000, 3))
module.exports = {
Power: Power
};

View File

@@ -1,138 +0,0 @@
<!--
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-27 08:39:46
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-12 22:01:34
-->
## 剑指Offer算法
> 刷题平台:牛客网
> 语言版本JavaScript
### 数组和矩阵
- [【简单】数组中重复的数字](./数组和矩阵/duplicate.js)
- [【中等】二维数组中的查找](./数组和矩阵/Find.js)
- [【较难】替换空格](./数组和矩阵/replaceSpace.js)
- [【较难】顺时针打印矩阵](./数组和矩阵/printMatrix.js)
- [【简单】第一个只出现一次的字符位置](./数组和矩阵/FirstNotRepeatingChar.js)
### 栈队列堆
- [【简单】两个栈实现队列](./栈队列堆/JSStackToQueue.js)
- [【中等】最小的k个数](./栈队列堆/GetLeastNumbers_Solution.js)
- [【中等】数据流中的中位数](./栈队列堆/InsertAndGetMedian.js)
- [【中等】字符流中的第一个不重复的字符](./栈队列堆/FirstAppearingOnce.js)
- [【较难】滑动窗口的最大值](./栈队列堆/maxInWindows.js)
- [【较难】包含min函数的栈](./栈队列堆/GetMinInJSStack.js)
- 栈的压入、弹出序列
### 双指针
- [【中等】和为S的两个数字](./双指针/FindNumbersWithSum.js)
- [【中等】和为S的连续正数序列](./双指针/FindContinuousSequence.js)
- [【中等】左旋转字符串](./双指针/LeftRotateString.js)
- [【较难】翻转单词顺序列](./双指针/ReverseSentence.js)
### 链表
- [【简单】合并两个排序的链表](./链表/Merge.js)
- [【简单】两个链表的第一个公共结点](./链表/FindFirstCommonNode.js)
- [【中等】链表中倒数第K个结点](./链表/FindKthToTail.js)
- [【中等】反转链表](./链表/ReverseList.js)
- [【较难】从尾到头打印链表](./链表/printListFromTailToHead.js)
- ~~在O(1)时间内删除链表节点~~
- [【较难】删除链表中重复的结点](./链表/deleteDuplication.js)
- 链表中环的入口结点[暂时没思路]
- 【较难】复杂链表的复制[暂时没有思路]
### 树
- [【中等】重建二叉树](./树/reConstructBinaryTree.js)
- [【中等】二叉树的下一个结点](./树/GetNext.js)
- [【较难】树的子结构](./树/HasSubtree.js)
- [【简单】二叉树的镜像](./树/Mirror.js)
- [【困难】对称的二叉树](./树/isSymmetrical.js)
- 从上往下打印二叉树
- 把二叉树打印成多行
- 二叉搜索树的后续遍历序列
- 【较难】二叉树中和为某一值的路径
- 二叉搜索树和双向链表
- 序列化二叉树
- 二叉查找树的第K个结点
- 二叉树的深度
- 平衡二叉树
- 树中两个节点的最低公共祖先
### 综合类型
#### 贪心思想
- 剪绳子
- [【LeetCode题目】股票的最大利润](./贪心思想/maxProfit.js)
#### 二分查找
- [【简单】旋转数组的最小数字](./二分查找/minNumberInRotateArray.js)
- [【中等】数字在排序数组中出现的次数](./二分查找/GetNumberOfK.js)
#### 分治
- [【中等】数值的整数次方](./分治/Power.js)
#### 搜索
- 矩阵中的路径 有难度
- 机器人的运动范围
- 字符串的排列
#### 排列
- [【中等】调整数组顺序使奇数位于偶数前面](./排列/reOrderArray.js)
- [【较难】把数组排成最小的数](./双指针/ReverseSentence.js)
- 数组中的逆序对 困难
#### 动态规划
- [【入门】斐波拉契数列](./动态规划/Fibonacci.js)
- [【简单】变态跳台阶 找规律 可跳任意阶](./动态规划/jumpFloorII.js)
- [【简单】连续子数组的最大和 时间复杂度O(n)](./动态规划/FindGreatestSumOfSubArray.js)
- [【简单】构建乘积数组](./动态规划/multiply.js)
- [【中等】矩形覆盖](./动态规划/rectCover.js)
- [【中等】跳台阶 非递归,要么跳一阶,要么跳两阶](./动态规划/jumpFloor.js)
- [【较难】丑数](./动态规划/GetUglyNumber_Solution.js)
#### 数学问题
- [【简单】数组中出现次数超过一半的数字](./数学/MoreThanHalfNum_Solution.js)
- [【中等】圆圈中最后剩下的数 约瑟夫问题](./数学/LastRemaining_Solution.js)
- [【中等】从1到n整数中1出现的次数](./数学/NumberOf1Between1AndN_Solution.js)
#### 位运算
- [【中等】二进制中1的个数](./位运算/NumberOf1.js)
- [【中等】数组中只出现一次的数字]()
#### 其他分类
- [【简单】不用加减乘除做加法](./其他相关/Add.js)
- [【中等】扑克牌顺子](./其他相关/IsContinuous.js)
- [【较难】把字符串转换成整数](./其他相关/StrToInt.js)

View File

@@ -1,50 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-23 22:26:26
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-23 22:40:59
*/
// odd 奇数 even: 偶数
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @return int整型一维数组
*/
/**
*
* 借用临时变量 遍历 【可通过测试】
* @param {Array} array
* @returns
*/
function reOrderArray( array ) {
// write code here
// 奇数,偶数;
let odd_arr=[],even_arr=[];
for(let index=0;index<array.length;index++){
if(array[index]%2!==0){
// 奇数
odd_arr.push(array[index])
}else{
// 偶数
even_arr.push(array[index])
}
}
// 拼接
return odd_arr.concat(even_arr)
}
console.log(reOrderArray([2,4,6,5,7]))
module.exports = {
reOrderArray : reOrderArray
};

View File

@@ -1,27 +0,0 @@
/*
* @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
};

View File

@@ -1,107 +0,0 @@
/*
* @Description: 【中等】数字在排序数组中出现的次数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-03 15:36:38
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-03 15:37:54
*/
function GetNumberOfK (data, k) {
// write code here
// 注意数组升序
let firstIndex = data.indexOf(k);
let lastIndex = data.lastIndexOf(k);
if (firstIndex === -1 || lastIndex === -1) {
return 0
}
return lastIndex - firstIndex < 0 ? 0 : lastIndex - firstIndex + 1
}
// 利用二分查找
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
}
// [leftright]
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
}
module.exports = {
GetNumberOfK: GetNumberOfK
};

View File

@@ -1,35 +0,0 @@
/*
* @Description: 【简单】旋转数组的最小数字
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-03 15:12:26
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-03 15:31:34
*/
// 找出前者大于后者的数,立即返回
function minNumberInRotateArray (rotateArray) {
// write code here
if (rotateArray.length < 0) {
return 0
}
for (let index = 0; index < rotateArray.length - 1; index++) {
if (rotateArray[index] > rotateArray[index + 1]) {
return rotateArray[index + 1]
}
}
// 返回
return rotateArray[0]
}
// 考虑二分法
function minNumberInRotateArray01(array){
}
module.exports = {
minNumberInRotateArray: minNumberInRotateArray
};

View File

@@ -1,87 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 23:31:16
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 23:31:26
*/
function FindNumsAppearOnce (array) {
// write code here
// 数组中元素要么出现一次,要么出现两次,可以先对元素进行排序 Math.sort((a,b)=>a-b) 从小到大 有点偷懒的样子
array = quickSort(array, 0, array.length - 1);
// 此时的 数组已经进过排序
let result = []
// 出现一次的元素,在中间
for (let index = 1; index < array.length - 1; index++) {
if (array[index - 1] !== array[index] && array[index] !== array[index + 1]) {
result.push(array[index])
}
}
// 假设在开头
if (array[0] !== array[1]) {
result.push(array[0])
}
// 假设在结尾
if (array[array.length - 1] !== array[array.length - 2]) {
result.push(array[array.length - 1])
}
// 过滤掉只出现一次的元素, 进行排序从小到大;
return result.sort((a, b) => a - b)
}
function quickSort (arr, left, right) {
if (left < right) {
const pivot = partition(arr, left, right);
// 左侧
quickSort(arr, left, pivot - 1)
// 右侧
quickSort(arr, pivot + 1, right)
}
return arr;
}
function partition (arr, left, right) {
let pivot = arr[left];
while (left < right) {
while (left < right && pivot <= arr[right]) --right;
arr[left] = arr[right];
while (left < right && pivot >= arr[left]) ++left;
arr[right] = arr[left]
}
arr[left] = pivot;
return left
}
module.exports = {
FindNumsAppearOnce: FindNumsAppearOnce
};

View File

@@ -1,30 +0,0 @@
/*
* @Description: 【中等】二进制中1的个数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-09 11:27:14
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-09 11:40:28
*/
function NumberOf1(n){
// 记录1的个数
let count=0;
// 循环验证
while(n!==0){
//加+1 记录
count++;
// 取与
n=n & (n-1)
}
return count;
}
// 当然也是可以转化为字符串,进行校验
module.export={
NumberOf1:NumberOf1
}

View File

@@ -1,32 +0,0 @@
/*
* @Description: 【简单】不用加减乘除做加法
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 21:29:19
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 23:25:36
*/
function Add (num1, num2) {
// write code here
let count = num1;
if (num2 > 0) {
for (let index = 0; index < num2; index++) {
count++
}
return count;
} else if (num2 < 0) {
let temp = Math.abs(num2);
for (let index = 0; index < temp; index++) {
count--
}
return count;
} else {
return count;
}
}
module.exports = {
Add: Add
};

View File

@@ -1,52 +0,0 @@
/*
* @Description: 【中等】扑克牌顺子
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 21:26:28
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 21:27:09
*/
function IsContinuous (numbers) {
// write code here
// 先对数据进行从小到大排列
numbers = numbers.sort((a, b) => a - b);
// 判断0的个数
let count = 0;
for (let index = 0; index < numbers.length; index++) {
if (numbers[index] === 0) {
count++;
}
}
// 不允许5个0
if (count > 4) {
return false;
}
// 4个0的时候一定成立
if (count === 4) {
return true;
}
// 判断每个的间隔
for (let index = 0; index < numbers.length - 1; index++) {
if (numbers[index] !== 0 && numbers[index + 1] - numbers[index] > 1) {
// console.log(count,(numbers[index+1]-numbers[index]))
count -= (numbers[index + 1] - numbers[index] - 1)
// console.log(count)
}
}
if (count === 0) {
return true;
}
return false;
}
module.exports = {
IsContinuous: IsContinuous
};

View File

@@ -1,23 +0,0 @@
/*
* @Description: 【较难】把字符串转换成整数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 21:40:03
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 23:28:22
*/
function StrToInt (str) {
// write code here
if (!str) return 0
let bool = false, firstLetter = str[0]
if (firstLetter == '-') bool = true
if (firstLetter == '-' || firstLetter == '+') str = str.substring(1)
const n = Number(str)
if (n === 0) return 0
return n !== n ? 0 : bool ? -n : n
}
// console.log(StrToInt(-123))
module.exports = {
StrToInt: StrToInt
};

View File

@@ -1,38 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-03 15:43:06
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-03 15:44:38
*/
function Power (base, exponent) {
// write code here
let result = 1;
if (exponent > 0) {
// 正数
while (exponent > 0) {
result *= base;
exponent--
}
return result;
} else if (exponent < 0) {
// 负数 取反 绝对值 abs
// let abs=Math.abs(exponent)
let abs = -exponent;
while (abs > 0) {
result *= base;
abs--
}
// 分数处理
return 1 / result;
} else {
// 0 返回1
return result;
}
}
module.exports = {
Power: Power
};

View File

@@ -1,41 +0,0 @@
/*
* @Description: 【入门】斐波拉契数列
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 11:00:05
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 11:10:56
*/
function Fibonacci (n) {
// write code here
// 递归调用
return n < 2 ? n : Fibonacci(n - 1) + Fibonacci(n - 2)
}
// 非递归实现
function Fibonacci01 (n) {
let a = 0, b = 1;
if (n < 2) {
return n;
}
let result = 0
for (let index = 2; index <= n; index++) {
// 求和
result = a + b;
a = b;
b = result;
}
// 返回结果
return result;
}
module.exports = {
Fibonacci: Fibonacci01
};

View File

@@ -1,35 +0,0 @@
/*
* @Description: 【简单】连续子数组的最大和 时间复杂度O(n)
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 11:34:21
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 11:45:11
*/
function FindGreatestSumOfSubArray (array) {
// 标记指针
let index = 0;
// 子串的累计结果
let sum = 0;
// 子串的累加和最大值,当标记位从
let max = array[index];
// 循环
while (index < array.length) {
sum += array[index];
max = sum > max ? sum : max;
// 注意,重新计数,累计求和从0开始
sum = sum > 0 ? sum : 0
index++
}
return max;
}
module.exports = {
FindGreatestSumOfSubArray: FindGreatestSumOfSubArray
};

View File

@@ -1,47 +0,0 @@
/*
* @Description: 【较难】丑数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-06 21:33:38
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-08 23:53:19
*/
function GetUglyNumber_Solution (index) {
// 由于丑数只包含因子 2 3 5 且下一个丑数是通过上一个丑数去x2 x3 或 x5 取最小得到的,要保证丑数的顺序递增的
// 定义存放丑数的数组且第一个丑数为1=2^0 * 3^0 * 5^0
let result=[1];
// 定义丑数对应的因子个数 即 丑数= 2^f2 * 3^f3 * 5^f5
let f2=0,f3=0,f5=0;
// 基于丑数的上下关系,可以去动态规划来做
for(let i=1;i<index;i++){
// 第i个丑数是在第i-1个丑数的基础上 去x2 x3 或 x5 取最小得到的存放在result中
result[i]=Math.min(result[i-1]*2,result[i-1]*3,result[i-1]*5);
if(result[i]===result[i-1]*f2){
f2++
}
if(result[i]===result[i-1]*f3){
f3++
}
if(result[i]===result[i-1]*f5){
f5++
}
}
console.log(result)
return result[index-1]
}
module.export = {
GetUglyNumber_Solution: GetUglyNumber_Solution
}

View File

@@ -1,50 +0,0 @@
/*
* @Description: 【中等】跳台阶 递归,要么跳一阶,要么跳两阶
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-28 23:41:55
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 11:32:38
*/
/**
*
* 思路: 对于第number台阶只能从第number-1或者number-2上跳上来
* 记作: G(number)=G(number-1)+G(number-2)
* 即: 从第number-1跳上来的次数+从第number-2上跳上来的次数
*
*/
// 递归实现
function jumpFloor (number) {
// write code here
// 递归,要么跳一阶,要么跳两阶
return number < 3 ? number : jumpFloor(number - 1) + jumpFloor(number - 2)
}
// 非递归调用
function jumpFloor01 (number) {
let a = 1;
let b = 2;
let result = 0;
if (number < 3) {
return number
}
for (let index = 3; index <= number; index++) {
result = a + b;
a = b;
b = result;
}
// 返回
return result;
}
module.exports = {
jumpFloor: jumpFloor
};

View File

@@ -1,31 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-28 23:41:50
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 11:26:46
*/
function jumpFloorII (number) {
// write code here
// 我tm跳1 还剩下n-1阶 记作 G(n-1) 可选
// 我tm跳2 还剩下n-2阶 记作 G(n-2) 可选
// ....
// 我tm跳n-1 还剩下1阶 记作 G(1) 可选
// 归纳出: G(n-1)=G(1)+G(2)+.....+G(n-2);
// G(n)=G(1)+G(2)+.....+G(n-2)+G(n-1)
// 两个相减 G(n)=2* G(n-1) 去递归 G(1)=1 , G(2)=2 G(3)=2*G(2)=4
// 开始代码
// return Math.pow(2,number-1)
// 位运算
// return 1<<(number-1)
return 1 << --number
}
module.exports = {
jumpFloorII: jumpFloorII
};

View File

@@ -1,23 +0,0 @@
/*
* @Description: 【简单】构建乘积数组
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-24 11:51:20
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 12:48:43
*/
function multiply (array) {
let result = [];
for (let index = 0; index < array.length; index++) {
// result.push(array.slice(0, index).reduce((res, item) => res * item, 1) * array.slice(index + 1).reduce((res, item) => res * item, 1))
result.push([...array.slice(0, index), ...array.slice(index + 1)].reduce((res, item) => {
return res * item;
},1)) // 给res的初始值为1
}
return result;
}
console.log(multiply([1, 2, 3, 4, 5]))

View File

@@ -1,36 +0,0 @@
/*
* @Description: 【中等】矩形覆盖
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 11:17:02
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 11:18:08
*/
function rectCover (number) {
// write code here
// 应该也是个递归 斐波拉契变形
// n=1 ---> 1
// n=2 ---> 2
// n=3 ---> 3 <---- 1+2
// n=4 ---> 5 <---- 2+3
let a = 1; // n=1的情况
let b = 2; // n=2的情况
if (number < 3) {
return number;
}
let result = 0;
for (let index = 3; index <= number; index++) {
result = a + b;
a = b;
b = result;
}
return result;
}
module.exports = {
rectCover: rectCover
};

View File

@@ -1,52 +0,0 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-30 21:05:44
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-30 21:36:15
*/
// 注意是连续递增数列间距为1 那么可以将序列开始、结束元素看做 a 、 b
// 按照数列求和公式sum=(首项+尾项)* 项数 /2 即可
function FindContinuousSequence (sum) {
// 按照sum值先预估大概最多满足条件的序列
// sum=(b+a)(b-a+1)/2
let left = 1, right = 2;
let result = [];
while (left < right) {
// 从left....right的序列求和
const temp_sum = (right + left) * (right - left + 1)
if (2 * sum === temp_sum) {
// 满足条件
let count = left;
let temp_arr = [];
while (count <= right) {
temp_arr.push(count)
count++
}
result.push(temp_arr)
// 向前寻找
left++
} else if (2 * sum > temp_sum) {
// 右边向右
right++
} else {
// 左边向右
left++
}
}
return result;
}
// console.log(FindContinuousSequence(9))
module.exports = {
FindContinuousSequence: FindContinuousSequence
};

View File

@@ -1,76 +0,0 @@
/*
* @Description: 【中等】和为S的两个数字
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-30 20:29:08
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-30 21:04:46
*/
// 根据x+y=sum 求xy最小 由于array是递增的则x y 距离越远 xy值越小x y距离越近xy值越大
// x+y=(x+m)+(y-m)=sum 假设x是左边元素y是右边元素 即y>x
// 可以理解乘积(x+m)(y-m)=xy-(y-x)*m-m^2 其中y-x>0 m^2
// 所以m值越大其实(x+m)(y-m)越小也就是x与y间隔也大 xy越小 由于array是递增的所以只需要找到第一个满足和为sum的即可
function FindNumbersWithSum (array, sum) {
let left = 0, right = array.length - 1;
while (left < right) {
if (array[left] + array[right] === sum) {
// 第一个就返回
return [array[left], array[right]]
} else if (array[left] + array[right] > sum) {
// 向左
right--
} else {
// 向右
left++
}
}
// 不存在满足添加,就返回空数组
return []
}
// 注意数组array是递增的
// 不存在的时候,返回空数组
function FindNumbersWithSum01 (array, sum) {
let left = 0, right = array.length - 1;
// 将最小值标记设置成最大
let min = array[right] * array[right]
let result = [];
while (left < right) {
if (array[left] + array[right] === sum) {
// 符合条件
if (min > array[left] * array[right]) {
// 最小值
min = array[left] * array[right]
result = [array[left], array[right]]
}
// 移动指针
left++;
right--
} else if (array[left] + array[right] < sum) {
// 左边向右
left++
} else {
// 右边向左
right--
}
}
// 跳出循环
return result;
}
console.log(FindNumbersWithSum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], 21))
module.exports = {
FindNumbersWithSum: FindNumbersWithSum
};

View File

@@ -1,50 +0,0 @@
/*
* @Description: 【中等】左旋转字符串
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-30 22:00:13
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-30 22:16:13
*/
function LeftRotateString (str, n) {
// write code here
// 临界条件
if(!str||str.length<n){
return ''
}
// 对k以前的进行翻转
const firstStr = str.slice(0, n);
// 对k以后的字符串进行翻转
const secondStr = str.slice(n);
// 对拼接后的字符串进行翻转
return reverseStr(`${reverseStr(firstStr)}${reverseStr(secondStr)}`)
}
// 偷懒做法
function LeftRotateString01 (str, n) {
// 两两翻转后,在统一翻转
return `${str.slice(0, n).split('').reverse().join('')}${str.slice(n).split('').reverse().join('')}`.split('').reverse().join('')
}
/**
* 旋转数组,交换
* @param {string} str
* @returns
*/
function reverseStr (str) {
let result = str.split('')
let left = 0, right = result.length - 1
while (left <= right) {
// 临时值 元素交换
[result[left], result[right]] = [result[right], result[left]]
left++;
right--
}
return result.join('');
}
console.log(LeftRotateString('',6))
module.exports = {
LeftRotateString: LeftRotateString
};

View File

@@ -1,54 +0,0 @@
/*
* @Description: 翻转单词顺序列
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-30 21:40:57
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-30 21:54:47
*/
// 偷懒做法
function ReverseSentence (str) {
// write code here
return str.split(' ').reverse().join(' ');
}
// 先将每个字符翻转 再将所有翻转
// nowcoder. a am I ---> .redocwon a ma I -----> I am a nowcoder.
function ReverseSentence01 (str) {
// write code here
let arr = str.split(' ');
for (let index = 0; index < arr.length; index++) {
// 翻转字符串
arr[index] = reverseStr(arr[index])
}
// 翻转数组 拼接
return reverseArr(arr).join(' ')
}
function reverseStr (str) {
let result = '';
for (let index = str.length - 1; index >= 0; index--) {
result += str[index]
}
return result;
}
function reverseArr (arr) {
let result = [];
for (let index = arr.length - 1; index >= 0; index--) {
result.push(reverseStr(arr[index]))
}
return result;
}
console.log(ReverseSentence01('nowcoder. a am I'))
module.exports = {
ReverseSentence: ReverseSentence
};

View File

@@ -1,35 +0,0 @@
/*
* @Description: 【较难】把数组排成最小的数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 07:58:03
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 07:59:26
*/
// 比较s1,s2的时候注意比较s1+s2<s2+s1的拼接大小
function PrintMinNumber (numbers) {
// write code here
let len = numbers.length;
// 冒泡每次都将最小的放在最前面
while (len > 0) {
for (let index = 0; index < numbers.length - 1; index++) {
if (parseInt(`${numbers[index]}${numbers[index + 1]}`) >= parseInt(`${numbers[index + 1]}${numbers[index]}`)) {
// 元素交换
[numbers[index], numbers[index + 1]] = [numbers[index + 1], numbers[index]]
}
}
len--
}
return numbers.join('')
}
module.exports = {
PrintMinNumber: PrintMinNumber
};

View File

@@ -1,34 +0,0 @@
/*
* @Description: 【中等】调整数组顺序使奇数位于偶数前面
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-03 15:56:06
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 07:54:38
*/
// 利用空间
function reOrderArray (array) {
// write code here
// 奇数,偶数;
let odd_arr = [], even_arr = [];
for (let index = 0; index < array.length; index++) {
if (array[index] % 2 !== 0) {
// 奇数
odd_arr.push(array[index])
} else {
// 偶数
even_arr.push(array[index])
}
}
// 拼接
return odd_arr.concat(even_arr)
}
// 利用冒泡,遇见偶数往最后放,统一前移
module.exports = {
reOrderArray: reOrderArray
};

View File

@@ -1,72 +0,0 @@
/*
* @Description: 【中等】圆圈中最后剩下的数 约瑟夫问题
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 14:48:28
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 15:11:02
*/
// 把n个人的编号改为0~n-1然后对删除的过程进行分析。
// 第一个删除的数字是(m-1)%n几位k则剩余的编号为(0,1,...,k-1,k+1,...,n-1),下次开始删除时,顺序为(k+1,...,n-1,0,1,...k-1)。
// 用f(n,m)表示从(0~n-1)开始删除后的最终结果。
// 用q(n-1,m)表示从(k+1,...,n-1,0,1,...k-1)开始删除后的最终结果。
// 则f(n,m)=q(n-1,m)。
// 下面把(k+1,...,n-1,0,1,...k-1)转换为(0~n-2)的形式,即
// k+1对应0
// k+2对于1
// ...
// k-1对应n-2
// 转化函数设为p(x)=(x-k-1)%n, p(x)的逆函数为p^(x)=(x+k+1)%n。
// 则f(n,m)=q(n-1,m)=p^(f(n-1,m))=(f(n-1,m)+k+1)%n又因为k=(m-1)%n。
// 取余
// f(n,m)=(f(n-1,m)+m)%n;
// 最终的递推关系式为
// f(1,m) = 0; (n=1)
// f(n,m)=(f(n-1,m)+m)%n; n>1
function LastRemaining_Solution (n, m) {
// write code here
// 递推公式: f(0)=-1 f(1)=0 f(i)={f(i-1)+m}%i
if (n === 0) {
return -1;
}
if (n === 1) {
return 0;
}
// 递归
return (LastRemaining_Solution(n - 1, m) + m) % n;
}
// 非递归实现
function LastRemaining_Solution01 (n, m) {
// 当然,这里也可以添加上负数的校验情况
if (n === 0) {
return -1;
}
if (n === 1) {
return 0
}
// 循环处理
let result = 0
for (let index = 2; index <= n; index++) {
// f(n,m)=[f(n-1,m)+m]%n
result = (result + m) % index
}
// 返回
return result;
}
module.exports = {
LastRemaining_Solution: LastRemaining_Solution
};

View File

@@ -1,40 +0,0 @@
/*
* @Description: 【 简单】数组中出现次数超过一半的数字
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-05 14:28:36
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 14:29:22
*/
// 借助map计数即可
function MoreThanHalfNum_Solution (numbers) {
// write code here
let map = new Map();
numbers.forEach(item => {
if (map.has(item)) {
map.set(item, map.get(item) + 1)
} else {
map.set(item, 1)
}
})
const arr = [...new Set(numbers)];
// console.log(map,arr)
let result = 0;
arr.map(item => {
if (2 * map.get(item) > numbers.length) {
result = item;
}
})
return result;
}
module.exports = {
MoreThanHalfNum_Solution: MoreThanHalfNum_Solution
};

View File

@@ -1,34 +0,0 @@
/*
* @Description: 【中等】从1到n整数中1出现的次数
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-26 22:23:17
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-05 15:15:56
*/
// 转化
function NumberOf1Between1AndN_Solution(n)
{
// write code here
let count=0;
while(n>0){
// 转化为字符串
count += (n).toString().split('').reduce((sum,item)=>{
if(item==='1'){
sum++;
}
return sum;
},0)
// 递减
n--
}
return count;
}
// console.log(NumberOf1Between1AndN_Solution(13))
module.exports = {
NumberOf1Between1AndN_Solution : NumberOf1Between1AndN_Solution
};

View File

@@ -1,100 +0,0 @@
/*
* @Description: 二维数组中的查找
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-27 08:52:21
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-27 10:00:41
*/
/**
*
* 每一行都按照从左到右递增的顺序排序
* 每一列都按照从上到下递增的顺序排序
*
* 直接循环找 选取右上或者左下元素为起点
*
*/
// 右上角元素为起点,确保每个元素都能遍历到,都能按照方向走即可
function Find (target, array) {
// write code here
// 行数
let row = array.length;
if (row === 0) {
return false;
}
// 列数
let col = array[0].length
// 此时选择右上为起点
let r = 0, c = col - 1
while (r < row && c >= 0) {
if (target === array[r][c]) {
// 命中目标,返回
return true;
} else if (target < array[r][c]) {
// 目标元素比右上小target往左找
c--
} else if (target > array[r][c]) {
// 目标元素比当前元素大target往下找
r++
}
}
return false;
}
// 比较蠢的方法,通过遍历二维数组进行比较
// 这里可以将第二层循环改成二分查找【用到从左到右递增的特点】;降低时间复杂度
// 这里的时间复杂度为O(nlogn)
function Find01(target,array){
let row = array.length;
if (row === 0) {
return false;
}
// 列数
let col = array[0].length
// 从第0行开始
for(let r=0;r<row;r++){
let low=0,high=col-1;
// 注意这个二分查找区间是 []
while(low<=high){
const mid=low+ Math.floor((high-low)/2);
if(array[r][mid]===target){
return true;
}else if(array[r][mid]>target){
// 在左侧,从左边找
high=mid-1;
}else if(array[r][mid]<target){
// 在右侧
low=mid+1
}
}
}
return false;
}
// 利用一些api
// every()是对数组中每一项运行给定函数如果该函数对每一项返回true,则返回true。
// some()是对数组中每一项运行给定函数如果该函数对任一项返回true则返回true。
function Find02(target,array){
return array.some(arr=>{
return arr.some(item=>item===target)
})
}
console.log(Find02(19,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]))
module.exports = {
Find: Find
};

View File

@@ -1,41 +0,0 @@
/*
* @Description: 第一个只出现一次的字符位置
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-28 22:23:51
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-28 22:24:20
*/
function FirstNotRepeatingChar (str) {
// write code here
// 转换为数组
let arr = str.split('');
// 数组里面去去重
for (let index = 0; index < arr.length; index++) {
if (arr.indexOf(arr[index]) === arr.lastIndexOf(arr[index])) {
return index
}
}
return -1
}
function FirstNotRepeatingChar01 (str) {
// write code here
const len = str.length;
for (let index = 0; index < len - 1; index++) {
const s = str.slice(index, index + 1);
if (`${str.slice(0, index)}${str.slice(index + 1)}`.indexOf(s) === -1) {
return index;
}
}
return -1
}
module.exports = {
FirstNotRepeatingChar: FirstNotRepeatingChar
};

View File

@@ -1,54 +0,0 @@
/*
* @Description: 数组中重复的数字
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-27 08:41:26
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-27 08:51:03
*/
/**
*
* 方案一:将所有数据从小打到排序,如果存在左右相等的情况就是重复了,输出一个即可;
* 方案二借助空数组循环遍历目标数组按照index的值放入 如果存在则重复
*
*
*/
function duplicate (numbers) {
// write code here
let arr = [];
for (let i = 0; i < numbers.length; i++) {
// 这部分依赖的是排序后如果不重复理想情况下numbers[index]===index的情况
if (!arr[numbers[i]]) {
arr[numbers[i]] = 1;
} else {
return numbers[i]
}
}
return -1
}
// 存在问题时间复杂度依赖sort()函数
function duplicate01 (numbers) {
// 从小到大排列
numbers = numbers.sort((a, b) => a - b)
for (let index = 0; index < numbers.length - 1; index++) {
if (numbers[index] === numbers[index + 1]) {
// 存在两个元素重复
return numbers[index]
}
}
return -1;
}
module.exports = {
duplicate: duplicate
};

View File

@@ -1,78 +0,0 @@
/*
* @Description: 顺时针打印矩阵
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-27 14:22:13
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-28 22:25:16
*/
function printMatrix (matrix) {
// write code here
// 行 角标
let row = matrix.length - 1;
// 列角标
if (matrix[0].length === 0) {
// 返回空数组
return []
}
let col = matrix[0].length - 1
let r = 0,
c = 0;
// 这里需要在脑海里想象顺时针旋转的时候r-->left c-->top row-->right col-->bottom
// 数组结果
let result = []
while (r <= row && c <= col) {
// 上
for (let index = c; index <= col; index++) {
// 当前在上测行为r 不为 row
result.push(matrix[r][index])
}
// 跳出后,到右侧
for (let index = r + 1; index <= row; index++) {
result.push(matrix[index][col])
}
// 跳出来,就是下测 判断右下角拐角
if (r !== row) {
// 从右到左边
for (let index = col - 1; index >= c; index--) {
// 当前在底部所以行为row
result.push(matrix[row][index])
}
}
// 左侧,注意判断条件
if (c !== col) {
// 从下到上
for (let index = row - 1; index > r; index--) {
// 当前在左侧所以列表为c 部位col
result.push(matrix[index][c])
}
}
// 指针移动 转完一圈
r++;
row--;
c++;
col--;
}
return result;
}
console.log(printMatrix([
[1, 2],
[3, 4]
]))
module.exports = {
printMatrix: printMatrix
};

View File

@@ -1,31 +0,0 @@
/*
* @Description: 替换空格
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-27 10:07:45
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-27 10:08:59
*/
// 先转化为数组,再进行拼接
function replaceSpace( s ) {
// write code here
return s.split(' ').join('%20')
}
// 利用循环拼接然后slice剪切
function replaceSpace01( s ) {
// write code here
const arr=s.split(' ');
let str='';
for(let index=0;index<arr.length;index++){
str=str.concat('%20').concat(arr[index]);
}
return str.slice(3);
}
module.exports = {
replaceSpace : replaceSpace
};

View File

@@ -1,44 +0,0 @@
/*
* @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
};

View File

@@ -1,43 +0,0 @@
/*
* @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
};

View File

@@ -1,41 +0,0 @@
/*
* @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
};

View File

@@ -1,40 +0,0 @@
/*
* @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
};

View File

@@ -1,24 +0,0 @@
/*
* @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
};

View File

@@ -1,28 +0,0 @@
/*
* @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
};

View File

@@ -1,46 +0,0 @@
/*
* @Description: 【较难】二叉树中和为某一值的路径
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-12 22:01:00
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-12 22:01:45
*/
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function FindPath (root, expectNumber) {
// write code here
let result = [];
function dfs (root, target, temp_res) {
// 处理空树
if (root === null) {
return;
}
// 根结点,进数组
temp_res.push(root.val);
// 当前结点为叶子结点
if (root.left === null && root.right === null && target === root.val) {
result.push(temp_res)
}
// 不是叶子结点,向左向右子树递归
dfs(root.left, target - root.val, [...temp_res])
dfs(root.right, target - root.val, [...temp_res])
}
dfs(root, expectNumber, [])
return result;
}
module.exports = {
FindPath: FindPath
};

View File

@@ -1,52 +0,0 @@
/*
* @Description: 【中等】二叉树的下一个结点
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-11 15:38:02
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-11 15:40:20
*/
/*function TreeLinkNode(x){
this.val = x;
this.left = null;
this.right = null;
this.next = null;
}*/
function GetNext (pNode) {
// write code here
// 中序遍历 ---> 左-根(pNode)-右
// 所以这里pNode的下一个结点要么是pNode右子树的第一个最左结点左边的叶子结点
// 但是如果pNode的右子树为空则pNode的下个结点则为第一个左子树指向pNode的祖先结点
if (pNode.right !== null) {
// 存在右子树,寻找右子树的最左结点
let right_node = pNode.right;
while (right_node.left !== null) {
// 一直向左找
right_node = right_node.left;
}
// 跳出循环的时候right_node.left==null即:right_node为叶子结点
return right_node
} else {
// 右子树为空,则向上找
while (pNode.next !== null) {
let parent_node = pNode.next;
if (parent_node.left === pNode) {
return parent_node;
}
// 父结点的左子树不是指向给定的结点的话,则继续往上寻找父结点
pNode = pNode.next;
}
}
// 都找不到则返回null
return null;
}
module.exports = {
GetNext: GetNext
};

View File

@@ -1,54 +0,0 @@
/*
* @Description: 【较难】树的子结构
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-11 16:07:54
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-11 16:08:40
*/
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function HasSubtree (pRoot1, pRoot2) {
// write code here
// 空树的情况
if (pRoot1 === null || pRoot2 === null) {
return false;
}
// 1.假设子结构从根结点开始;
const is_root = isSubTreeWithRoot(pRoot1, pRoot2);
// 2 子结构从左、右子树开始;
const in_left = HasSubtree(pRoot1.left, pRoot2);
const in_right = HasSubtree(pRoot1.right, pRoot2);
// 三种满足一种,就是子结构了
return is_root || in_left || in_right;
}
// 判断root2是否为root1的子集【递归实现】
function isSubTreeWithRoot (root1, root2) {
// root2 自己为叶子结点,此时递归来看,就是子集
if (root2 === null) {
return true;
}
// 递归来看root1为空了就是非子集
if (root1 === null) {
return false;
}
// 判断两者元素是否匹配
if (root1.val !== root2.val) {
// 其中某个元素不配,递归断了
return false;
}
// 当前结点相同,继续递归校验后续左右子树结点,两树同时向左或者向右
return isSubTreeWithRoot(root1.left, root2.left) && isSubTreeWithRoot(root1.right, root2.right)
}
module.exports = {
HasSubtree: HasSubtree
};

View File

@@ -1,75 +0,0 @@
/*
* @Description: 【简单】二叉搜索树的第K个结点
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-12 19:51:41
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-12 20:26:21
*/
function ListNode (x) {
this.val = x;
this.left = null;
this.right = null;
}
// {8,6,10,5,7,9,11},1
const root = {
val: 8,
left: {
val: 6,
left: {
val: 5,
left: null,
right: null
},
right: {
val: 7,
left: null,
right: null
}
},
right: {
val: 10,
left: {
val: 9,
left: null,
right: null
},
right: {
val: 11,
left: null,
right: {
val: 12,
left: null,
right: null
}
}
}
}
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
// 注意,是返回结点
function KthNode (pRoot, k) {
// console.log(inOrder(pRoot))
return inOrder(pRoot)[k - 1]
}
// 中序遍历
function inOrder (root) {
// console.log(root)
if (root === null) {
return []
}
return inOrder(root.left).concat([root]).concat(inOrder(root.right))
}
module.exports = {
KthNode: KthNode
};

View File

@@ -1,47 +0,0 @@
/*
* @Description: 【简单】二叉树的镜像
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-11 16:42:42
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-11 16:43:17
*/
/*
* function TreeNode(x) {
* this.val = x;
* this.left = null;
* this.right = null;
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return TreeNode类
*/
function Mirror (pRoot) {
// write code here
// 空树
if (pRoot === null) {
return pRoot;
}
// 处理根节点,交换左右子树【建议封装函数】
[pRoot.left, pRoot.right] = [pRoot.right, pRoot.left]
// 左子树镜像
Mirror(pRoot.left)
// 右子树镜像
Mirror(pRoot.right)
return pRoot;
}
module.exports = {
Mirror: Mirror
};

Some files were not shown because too many files have changed in this diff Show More