1.在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。【2022.3.16】
选择最左下角的那个点作为起始点,
也就是a[array.lenth][0],比它大就往右边走,
比它小就往上面走。
2.请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。【2022.3.16】
return str.replace(/\s/g, '%20');
\s:正则表达式判断空格;
//g:全局判断
3.输入一个链表,从尾到头打印链表每个节点的值。【2022.3.17】
把链表遍历一遍,用头部添加的方式放到新数组中
while(head!==null){
str.unshift(head.val);
head=head.next;
}
如何定义一个链表测试!!
function ListNode(val) {
this.val = val;
this.next = null;
}
// 创建新的节点
let node1 = new ListNode(1);
let node2 = new ListNode('kk');
let node3 = new ListNode('ff');
node1.next = node2;
node2.next = node3
var a=printListFromTailToHead(node1);
console.log(a);
【2022.3.18】.知前序,中序重构二叉树
找到根节点,划分左子树,右子树
左右子树在分别递归遍历;
pre是前序遍历集合;Min是中序遍历集合;
return
{
left:reConstruct(pre.slice(1,index+1),left),
right:reConstruct(pre.slice(index+1),right)
};
【2022.3.18】.用两个栈实现队列
一个栈是入栈,一个栈是出栈;
outstack.push(instack.pop);
return outstack.pop
注意边界条件的判断:
if (!outStack.length) {
while (inStack.length)
昨天周六,休息一天
【2022.3.20】动态规划求解斐波拉契数列
动态规划的求解意思为:每一步的求解都用到上一次算出的答案;例如计算第三项的时候用第二项加第一项;
注意边界条件:n=1的时候已经直接输出,不做循环了
while (n--) {
g += f;
f = g - f;
}
return f;
【2022.3.21】6.旋转数组中的最小数字
只要找到数组中下一个数值小于前一个数值的临界点,即为最小值
for (let i = 0; i < rotateArray.length; i++) {
if (rotateArray[i] > rotateArray[i + 1]) return rotateArray[i + 1];
}
return rotateArray[0];
【2022.3.21】8.一只青蛙一次可以跳上1级台阶,也可以跳上2级。
斐波拉契问题变形:用动态规划问题求解
1.当第一步跳一个台阶时,剩下的跳法为f(n-1)
2.当第一步跳2个台阶时,剩下的跳法为f(n-2)
因此f(n)=f(n-1)+f(n-2);
判断初始条件:
有一个台阶,f(1)=1;
有两个台阶,f(2)=2;
ps!注意边界条件 while (--number)
let f = 1,//f为第一项
g = 2;//g为第二项
while (--number) {
g += f;
f = g - f;
}
return f;
}
斐波拉契这一类问题的常规写法:
if(number <= 0)
return 0;
else if(number == 1)
return 1;
else if(number == 2)
return 2;
else
return jumpFloor(number-1) + jumpFloor(number-2);
}
【2022.3.21】9. 变态跳台阶:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
解题思想:
a[n]=a[n-1]+a[n-2]+......+a[1];..........................①
a[n-1]= a[n-2]+......+a[1];..........................②
两式相减可知:a[n]=2*a[n-1];
【2022.3.22】10.21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法
思考:变相的斐波拉契数列问题
n=0; return 0;
n=1;f(1)=1;
n=2;f(2)=2;
其余条件下:
【2022.3.22】
一个一个向右移位,并且判断最右边的那个位是否为1,为1就count++,但是这样输入负数时会陷入死循环,因为负数右移时,最高位补得是1,那么这样会有无数个1。
因此选择把flag: 1 左移;
1左移 32 位后为 0;
```cpp
while(flag){
if(flag&n)
count++;
flag=flag << 1;
}
return count;```
【2022.3.22】【❤❤❤】这该死的题看了两天
12.给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
解法一:按位求解
此方法将幂次k看做二进制的数,一位一位的求解。比如k=10,即求a10,
10的二进制表示为1010。我们就可以把a10看成a8+a2。
就是对应二进制位为1的位置求幂,最后在相加。
这样就可以遍历幂次n的每个位来完成求幂运算
while (n) {
// 也可以用递归做,这里采用了循环
if (n & 1)
// 为1的时候把结果乘上去
{res *= base;}
base *= base;//底数翻倍
n >>= 1;//n右移动一位,继续判断下一位
}
解法二:递归求解
int pow1(int a,int k){
if(k==0) return 1;
else{
if(k%2) return a*pow(a,k-1);
else{
int tmp=pow(a,k/2);
return tmp*tmp;
}
}
}
知识点1:对于if(!a)来说,要看你给a的初值是什么,如果是一个非零值的话,那么!a就是假,不执行语句;
如果a的初值为零,那么!a就是真,执行语句
知识点2:左移和右移
【2022.3.24】(13)调整数组顺序使奇数位于偶数前面
思路:先找到奇数的个数,遍历数组每一个值:
是奇数的话,下标从0开始,放入新数组;
是偶数的话,下标从奇数个数下表开始奇数个数下标加一开始;
for (let i = 0; i < array.length; i++) {
if (array[i] & 1) {
newArray[oddBegin++] = array[i];
} else {
newArray[oddCount++] = array[i];
}
}
【2022.3.24】(14)链表中倒数第K个节点
双指针:一个在1,另一个在k;同时跑,
当一个指针达到最后一个时,那么前一个指针就是倒数第k个;
【2022.3.25】(15)反转链表:规定了必须用链表
:使用三个指针遍历单链表,逐个链接点进行反转。
1->2->3->4->5;(按照以下过程)
1->null;
2->1->null;
3->2->1->null;
4->3->2->1->null;
5->4->3->2->1->null; 最后返回5,就是新链表的头结点
// 三个节点
let preNode=null,aftNode=null;
while(pHead!==null){
aftNode=pHead.next; //记录下一节点
pHead.next=preNode;//指向前一节点
preNode=pHead;//当前头结点成为下次被指向的前一结点
pHead =aftNode;//当前下一节点成为新的头结点
}
return preNode;//最后一次被指向的前节点就是反转链表的头结点
【2022.3.25】16.合并两个排序的链表
递归实现:两个链表都是单挑递增的
不断地比较他们的头结点即可
if(pHead1.val<pHead2.val){
NewListHead=pHead1;
NewListHead.next=Merge(pHead1.next,pHead2);}
else{
NewListHead=pHead2;
NewListHead.next=Merge(pHead2.next,pHead1);
}
return NewListHead;
【2022.3.28】17.树的子结构 (B是A的子结构)
HasSubtree:判断 B 是否是 A 的子结构:从根节点开始判断,根节点相等的情况下,调用子函数判断;如果根节点不相等,下移A的根节点继续递归判断
IsSubtree:封装“判断 B 是否是 A 的子结构”的具体逻辑。不断遍历传入根节点的左右子树判断
function HasSubtree(pRoot1, pRoot2)
{
let result=false;
if(pRoot1==null||pRoot2==null) return false;
if(pRoot1.val==pRoot2.val) result=IsSubtree(pRoot1,pRoot2);
//该根节点不等,下移A的根节点
if(!result) result= HasSubtree(pRoot1.left,pRoot2);
if(!result) result= HasSubtree(pRoot1.right,pRoot2);
return result;
}
function IsSubtree(pRoot1, pRoot2)
{
//B都判等完了,说明B为A的子树
if(pRoot2==null) return true;
//A都判等完了还在继续找,说明B不是A的子树
if(pRoot1==null) return false;
if(pRoot1.val!==pRoot2.val) return false;
return IsSubtree(pRoot1.left,pRoot2.left)&&IsSubtree(pRoot1.right,pRoot2.right);
}
【2022.3.28】18.二叉树的镜像
思想:交换左右节点,递归
if(pRoot==null) return null;
[pRoot.right,pRoot.left]=[pRoot.left,pRoot.right];
Mirror(pRoot.left);
Mirror(pRoot.right);
return pRoot;
【2022.3.28】20.包含min函数的栈
实现栈的min函数:增加一个辅助栈
pop函数:原栈直接压入元素;minStack压入时比较一下
if(temp==null)
//temp等于空意味着第一次比较,这是直接把元素放进去即可;
//temp=node;用来记录元素,用于后续比较
{ temp=node;
stack.push(node);
minStack.push(node);}
//temp不为空意味着后续比较,压入之前和temp记录数值比较一下,
//temp始终记录最小值
else{
if(node<temp){
temp=node;
}
stack.push(node);
minStack.push(temp);
}
【2022.3.30】19.顺指针打印矩阵
【❤❤❤】这该死的题看了两天
定义两个函数:
1.通过两个坐标确定矩阵打印范围
2.根据坐标打印一整圈