1. 10个糖果 3个人分 每个人至少有一个糖果 有多少种分法? (逻辑 组合数列的问题)
//使用代码实现:
// 一个人 一个人 一个人
// 1 1 8
// 1 2 7
// 。。。
// 1 8 1 共有 8种分法
// 2 1 7
// 2 2 6
// 。。。
// 2 7 1 共有 7种分法
// 3 。。。 共有 6种分法
// 4 。。。 共有 5种分法
// 5 。。。 共有 4种分法
// 6 。。。 共有 3种分法
// 7 。。。 共有 2种分法
// 8 。。。 共有 1种分法
// 总共 有 8+7+。。。+1 = 36种
// var sum = 0;
// for (let i = 1; i <= 11; i++) {//一个for循环代表一个位置 一层
// for (let j = 1; j <= 11; j++) {//一个for循环代表一个位置 一层
// for (let k = 1; k <= 11; k++) {//一个for循环代表一个位置 一层 可以省略第三层
// if ((i+j+k)==10) {
// sum++
// }
// }
// }
// }
// console.log(sum)//不是最优的 10*10*10
//优化
// var sum = 0;
// for (let i = 1; i <= 11; i++) {//一个for循环代表一个位置 一层
// for (let j = 1; j <= 9; j++) {//一个for循环代表一个位置 一层
// for (let k = 1; k <= 8; k++) {//一个for循环代表一个位置 一层 可以省略第三层
// if ((i+j+k)==10) {
// sum++
// }
// }
// }
// }
// console.log(sum)//不是最优的 10*9*8
2. 百钱买百鸡 公鸡5文钱一只 母鸡3文钱一只 一文钱3只小鸡 有多少种买法?每种鸡至少需要买一种
// console.time("fn")
// var sum = 0;
// for (let i = 0; i <= 100; i++) {//一个for循环代表公鸡 一层
// for (let j = 0; j <= 100; j++) {//一个for循环代表一母鸡 一层
// for (let k = 0; k <= 100; k++) {//一个for循环代表小鸡 一层
// if ((i+j+k)==100 && (i*5+3*j+k/3)==100) {//条件的问题
// console.log(i+"--"+j+"--"+k)
// sum++
// }
// }
// }
// }
// console.log(sum)//不是最优的 100*100*100 百万次循环 《==》 优化 660次
// var sum = 0;
// for (let i = 1; i <= 20; i++) {//一个for循环代表公鸡 一层
//for (let j = 1; j <= 33; j++) {//一个for循环代表一母鸡 一层
// for (let k = 1; k <= 100; k++) {//一个for循环代表小鸡 一层
// k=100-i-j;
if ((i*5+3*j+k/3)==100) {//条件的问题
console.log(i+"--"+j+"--"+k)
sum++
}
}
}
}
console.log(sum)//不是最优的 100*100*100 百万次循环 《==》 优化 660次
3. 如果 a+b+c=1000,且 a^2+b^2=c^2(a,b,c 为自然数 勾股定理),如何求出所有a、b、c可能的组合?
// 循环次数 1000*1000*1000 = 1亿次 时间复杂度:T(n) = O(n*n*n) = O(n3) 空间复杂度
// console.time('serialFn')
// var count = 0;
// for (var a = 0; a < 1000 ; a++) {
// for (var b = 0; b < 1000 ; b++) {
// for (var c = 0; c < 1000 ; c++) {
// if ((a+b+c==1000) && (a*a+b*b==c*c)) {
// count++;
// console.log(a+":"+b+":"+c)
// }
// }
// }
// }
// console.log(count)
// console.timeEnd('serialFn')
//优化 循环次数 从 亿级别十万级别 时间复杂度:T(n) = O(n*n*(1+1)) = O(n*n) = O(n2)
// console.time('serialFn')
// var count = 0;
// for (var a = 0; a < 1000 ; a++) {
// for (var b = 0; b < 1000-a ; b++) {
// c = 1000-a-b;
// if ((a*a+b*b==c*c)) {
// count++;
// console.log(a+":"+b+":"+c)
// }
// }
// }
// console.log(count)
// console.timeEnd('serialFn')
//实现算法程序的执行时间可以反应出算法的效率,即算法的优劣
//评判一个算法的优劣 对于算法的时间效率 大O记法 : 时间复杂度 空间复杂度
//算法的优劣时间复杂度判断标准 O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
4. 逻辑题 算法题 有1分 2分 5分的硬币,求凑1元钱有多少种方法? 封装成函数 运行时间 get100: 190.869140625ms
// function get100(){
// console.time('get100')
// let count = 0;
// for (var a = 0; a < 100 ; a++) { //5分
// for (var b = 0; b < 100 ; b++) {//2分
// for (var c = 0; c < 100 ; c++) {//1分
// if ((a*5+b*2+c*1==100)) {
// count++;
// console.log(a+":"+b+":"+c)
// }
// }
// }
// }
// console.log(count)
// console.timeEnd('get100')
// }
// get100();
// function get100(){ //时间复杂度 o(n*n*n) 20*50*100
// console.time('get100')
// let count = 0;
// for (var a = 0; a <= 100/5 ; a++) { //5分
// for (var b = 0; b <= 100/2 ; b++) {//2分
// for (var c = 0; c <= 100/1 ; c++) {//1分
// if ((a*5+b*2+c*1==100)) {
// count++;
// console.log(a+":"+b+":"+c)
// }
// }
// }
// }
// console.log(count)
// console.timeEnd('get100')
// }
// get100();
// function get100(){ //优化 时间复杂度 o(n*n) 20*50*100 40.68115234375ms
// console.time('get100')
// let count = 0;
// for (var a = 0; a <= 100/5 ; a++) { //5分
// for (var b = 0; b <= 100/2 ; b++) {//2分
// if ((a*5+b*2<=100 )) {//优化 2分与5分的硬币加起来小于100就行
// count++;
// console.log(a+":"+b+":")
// }
// }
// }
// console.log(count)
// console.timeEnd('get100')
// }
// get100();
// function get100(){ //优化 时间复杂度 o(n) get100: 13.492919921875ms
// console.time('get100')
// let count = 0;
// for (var a = 0; a <= 100/5 ; a++) { //5分
// // if ((a*5+b*2<=100 )) {//优化 2分与5分的硬币加起来小于等于100就行,只选5分的硬币的数量,然后除以2就可以
// count+=Math.floor((100-a*5)/2);
// console.log(a+":")
// // }
// }
// console.log(count)
// console.timeEnd('get100')
// }
// get100();
数据结构只是静态的描述了数据元素之间的关系。高效的程序需要在数据结构的基础上设计和选择算法。程 序 = 数据结构 + 算法
总结:算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体
数据运算有五种 插入 删除 修改 查找 排序
数据结构: 顺序表、链表、栈、队列、树、图、 面试的时候 说数据结构 一脸蒙 扫盲
1: 线性表 线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系 分成
顺序表: 将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。 连续的存储区
时间复杂度为O(1)
链表: 将元素存放在通过链接构造起来的一系列存储块中。 通过链接(指针)构造起来存储块
单向链表 单向循环链表 双向链表
栈可以用顺序表实现,也可以用链表实现。
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
// 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构;用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。
// 树中任意节点的子节点之间有顺序关系,这种树称为有序树
// 二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)
// 完全二叉树:对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树,其中满二叉树的定义是所有叶节点都在最底层的完全二叉树;
// 满二叉树:
// 二叉树的遍历: 递归
// 深度优先遍历 DFS 三种遍历先序遍历(preorder 父——》左子树-》右子树),中序遍历(inorder 左子树——》父节点-》右子树)和后序遍历(postorder 左子树-》右子树——》父 )
// 广度优先遍历(层次遍历) BFS
// 图: