1
0
mirror of https://github.com/142vip/408CSFamily.git synced 2026-04-14 18:30:30 +08:00

[5.5 add nowcoder coding]

This commit is contained in:
mmdapl
2021-05-05 08:04:14 +08:00
parent fadc8053eb
commit bd1b40e4bc
21 changed files with 728 additions and 216 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
算法/.DS_Store vendored

Binary file not shown.

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

@@ -4,7 +4,7 @@
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-27 08:39:46
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-30 22:15:20
* @LastEditTime: 2021-05-05 07:59:56
-->
@@ -45,15 +45,16 @@
### 链表
- 从尾到头打印链表
- 在O(1)时间内删除链表节点
- 删除链表中重复的结点
- 链表中倒数第K个结点
- 链表中环的入口结点
- 反转链表
- 合并两个排序的链表
- 复杂链表的复制
- 两个链表的第一个公共结点
- [【简单】合并两个排序的链表](./链表/Merge.js)
- [【简单】两个链表的第一个公共结点](./链表/FindFirstCommonNode.js)
- [【中等】链表中倒数第K个结点](./链表/FindKthToTail.js)
- [【中等】反转链表](./链表/ReverseList.js)
- [【较难】从尾到头打印链表](./链表/printListFromTailToHead.js)
- ~~在O(1)时间内删除链表节点~~
- [【较难】删除链表中重复的结点](./链表/deleteDuplication.js)
- 链表中环的入口结点[暂时没思路]
- 【较难】复杂链表的复制[暂时没有思路]
### 树
@@ -78,31 +79,31 @@
### 贪心思想
- 剪绳子
- 股票的最大利润
- [【LeetCode题目】股票的最大利润](./贪心思想/maxProfit.js)
### 二分查找
- 旋转数组的最小数字
- 数字在排序数组中出现的次数
- [【简单】旋转数组的最小数字](./二分查找/minNumberInRotateArray.js)
- [【中等】数字在排序数组中出现的次数](./二分查找/GetNumberOfK.js)
### 分治
- 数值的整数次方
- [【中等】数值的整数次方](./分治/Power.js)
### 搜索
- 矩阵中的路
- 矩阵中的路径 有难度
- 机器人的运动范围
- 字符串的排列
### 排列
- 调整数组顺序使奇数位于偶数前面
- 把数组排成最小的数
- [【中等】调整数组顺序使奇数位于偶数前面](./排列/reOrderArray.js)
- [【较难】把数组排成最小的数](./双指针/ReverseSentence.js)
- 数组中的逆序对
### 动态规划

View File

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

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

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

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

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

@@ -4,10 +4,10 @@
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-04-29 23:27:18
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-04-29 23:27:55
* @LastEditTime: 2021-05-03 15:00:53
*/
/**
*
* 暴力
* @param prices int整型一维数组
* @return int整型
*/
@@ -29,6 +29,34 @@ function maxProfit (prices) {
// 返回最大值
return max;
}
/**
* 处理买点,卖点
* @param {number[]} prices
* @return {number}
*/
function maxProfit (prices) {
// 最大收益为0 其他都不算收益
let max = 0;
// 定义最小的值为买入
let minPrice = Infinity
for (let index = 0; index < prices.length; index++) {
let start = prices[index];
// 处理买点
if (start < minPrice) {
minPrice = start
}
// 处理卖点
if (start - minPrice > max) {
// 获取最大收益
max = start - minPrice
}
}
// 返回最大值
return max;
};
module.exports = {
maxProfit: maxProfit
};

View File

@@ -0,0 +1,21 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-02 15:58:48
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-02 15:58:58
*/
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function EntryNodeOfLoop (pHead) {
// write code here
}
module.exports = {
EntryNodeOfLoop: EntryNodeOfLoop
};

View File

@@ -0,0 +1,48 @@
/*
* @Description: 【简单】两个链表的第一个公共结点
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-02 21:33:19
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-02 21:44:24
*/
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function FindFirstCommonNode (pHead1, pHead2) {
// write code here
// 双重循环,时间复杂度过大,考虑优化
// while(pHead1!==null){
// let pHead2_back=pHead2
// while(pHead2_back!==null){
// if(pHead1===pHead2_back){
// return pHead1;
// }else{
// pHead2=pHead2_back.next;
// }
// }
// // 对pHead2从头开始
// pHead2_back=pHead2
// pHead1=pHead1.next;
// }
// return null;
let p1 = pHead1, p2 = pHead2;
// 其实,这里有个死循环的问题
while (p1 !== p2) {
// 不相等,则向前,如果后继结点为空,则回到头结点,重复
p1 = p1 === null ? pHead1 : p1.next;
p2 = p2 === null ? pHead2 : p2.next;
}
// 返回公共结点
return p1;
}
module.exports = {
FindFirstCommonNode: FindFirstCommonNode
};

View File

@@ -0,0 +1,74 @@
/*
* @Description:
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-02 15:47:20
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-02 15:55:43
*/
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
function FindKthToTail (pHead, k) {
// write code here
// 结点不存在返回空
if (pHead === null) {
return null;
}
// 遍历链表,
let count = 0;
let pre = pHead;
while (pHead) {
// 将数组进行头插
count++
pHead = pHead.next;
}
// 链表长度小于k,返回空
if (count < k) {
return null;
}
// 再对链表进行遍历
while (count > k) {
count--
pre = pre.next;
}
// 返回倒数k个结点
return pre;
}
// 上面是有两次while一次计数一次移动指针找到目标结点
// 可以利用数组,不能是头插入,还是尾插都行,存储的元素为链表的结点,也就是链表的子链表的头指针
function FindKthToTail01 (pHead, k) {
let result = []
while (pHead !== null) {
// 头插
result.unshift(pHead);
// 指针后移
pHead = pHead.next;
}
// k不合法
if (result.length < k) {
return null
}
// 用尾插的话,返回 result[result.length-k]
return result[k - 1]
}
module.exports = {
FindKthToTail: FindKthToTail01
};

View File

@@ -0,0 +1,76 @@
/*
* @Description: 【简单】合并两个排序的链表
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-02 17:18:36
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-02 17:30:18
*/
function ListNode (x) {
this.val = x;
this.next = null;
}
// 注意 两个链表都是单调递增
function Merge (pHead1, pHead2) {
// write code here
let pre = new ListNode(-1);
let result = pre
while (pHead1 !== null && pHead2 !== null) {
if (pHead1.val >= pHead2.val) {
// 前者大,用后者
result.next = pHead2;
pHead2 = pHead2.next;
} else if (pHead1.val < pHead2.val) {
// 后者大,用前者
result.next = pHead1;
pHead1 = pHead1.next;
}
// 后移指针
result = result.next;
}
if (pHead1 !== null) {
// 链表1没有走完
result.next = pHead1
}
if (pHead2 !== null) {
// 链表2没有走完
result.next = pHead2;
}
// 返回 注意去掉头结点
return pre.next;
}
// 思考递归的做法 没有上面迭代好理解
function Merge01(pHead1,pHead2){
if(pHead1===null){
return pHead2
}
if(pHead2===null){
return pHead1
}
// 前者大于后者,
if(pHead1.val>=pHead2.val){
// 记住pHead2向后
pHead2.next=Merge01(pHead1,pHead2.next)
return pHead2
}
// 前者小于后者
if(pHead1.val<pHead2.val){
pHead1.next=Merge01(pHead1.next,pHead2)
return pHead1;
}
}
module.exports = {
Merge: Merge
};

View File

@@ -0,0 +1,58 @@
/*
* @Description: 【中等】反转链表
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-02 16:13:46
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-02 16:36:52
*/
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
// 头插法
function ReverseList (pHead) {
// write code here
// 定义反转后链表
let result = null;
// let result=new ListNode(-1)
// 使用头插法
while (pHead) {
let currentNode = pHead;
pHead = pHead.next;
// 当前结点的后继结点为修改前的反转后的链表
currentNode.next = result;
// 翻转的链表的头结点指向头插法插入的结点
result = currentNode;
}
return result;
}
// 递归
function ReverseList01 (pHead) {
if (pHead === null || pHead.next === null) {
return pHead;
}
// head为当前链表的头结点
// 定义当前链表头结点的后继结点 【前提是前面判断其后继结点存在】
let nextNode = pHead.next;
// 此时将链表分为头结点+ 后继结点为头结点的子链表
// 对子链表进行反转,得到新的链表【这里是递归,先考虑一层,考虑其他容易乱】
let result = ReverseList01(nextNode);
// 在反转链表的result中原来是head后继结点当头结点的nextNode现在是result链表的尾结点
// 对原来的pHead的后继结点置null 此时的head应该为result的尾结点避免递归陷入死循环
pHead.next = null;
// 只需要将result的尾结点与head链接起来就是反转链表了
nextNode.next = pHead;
return result;
}
module.exports = {
ReverseList: ReverseList01
};

View File

@@ -0,0 +1,81 @@
/*
* @Description: 【较难】删除链表中重复的结点
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-02 09:02:18
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-02 09:15:24
*/
function ListNode (x) {
this.val = x;
this.next = null;
}
// 注意是排序的结点
// 这种先遍历,再借用临时变量 也可以考虑用递归
function deleteDuplication (pHead) {
// write code here
// 定义map
let map = new Map();
while (pHead) {
if (map.has(pHead.val)) {
// 存在
map.set(pHead.val, map.get(pHead.val) + 1)
} else {
// 不存在
map.set(pHead.val, 1)
}
// 下一个元素
pHead = pHead.next;
}
// 遍历map 找出值为1的
let result = new ListNode(-1)
let pre = result;
for (let m of map) {
const [key, count] = m;
// 尾插法
if (count === 1) {
// console.log(key)
result.next = new ListNode(key);
// 指针后移
result = result.next;
}
}
// pre为结果链表的头结点 ,去除-1
return pre.next;
}
// 基于递归
function deleteDuplication01 (head) {
if (head === null || head.next === null) {
return head;
}
// 前后结点都不为空比较val值
let nextNode = head.next;
if (head.val === nextNode.val) {
while (nextNode !== null && head.val === nextNode.val) {
// 值相同的情况 移动到下一个结点
nextNode = nextNode.next;
}
// 过滤掉值相同的,递归
return deleteDuplication01(nextNode)
} else {
// 值不同,将头结点的下一个位置指向
head.next = deleteDuplication01(head.next)
// 返回头结点
return head;
}
}
module.exports = {
deleteDuplication: deleteDuplication
};

View File

@@ -0,0 +1,73 @@
/*
* @Description: 【较难】从尾到头打印链表
* @Version: Beta1.0
* @Author: 【B站&公众号】Rong姐姐好可爱
* @Date: 2021-05-01 20:49:28
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
* @LastEditTime: 2021-05-01 21:24:40
*/
function ListNode (x) {
this.val = x;
this.next = null;
}
// 偷懒写法
function printListFromTailToHead (head) {
// write code here
// 只有单个指针,从头出链表,按序放入数组,最后翻转数组
let result = [];
while (head !== null) {
result.push(head.val);
// 下一个元素
head = head.next;
}
// 翻转并返回
return result.reverse()
}
// 先翻转链表【采用头插法】,再按序输入到数组中
function printListFromTailToHead01 (head) {
let reverseHead = new ListNode(-1);
// 头插法
while (head !== null) {
let pre = head;
// 下一个结点
head = head.next;
pre.next = reverseHead.next;
reverseHead.next = pre
}
// 重新整理 去掉val=-1的点
reverseHead = reverseHead.next
let result = []
// 遍历链表
while (reverseHead !== null) {
result.push(reverseHead.val);
// 下一个结点
reverseHead = reverseHead.next;
}
// 返回
return result;
}
// 相比链表的头插这里对数组array进行头插unshift()即可
function printListFromTailToHead02 (head) {
let result = [];
while (head !== null) {
result.unshift(head.val);
// 下一个结点
head = head.next;
}
// 返回,输出
return result;
}
module.exports = {
printListFromTailToHead: printListFromTailToHead
};