这篇是整理了一部分刷的算法题的大概解题思路,怕自己以后忘记,后续还会更新。
其中解题思路也会在代码中的注释有体现
二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
//因为每一行从左到右递增,从上到下递增,所以右上角的数是整个二维数组最大的数
//所以从右上角的数开始比较比target大就行数减一,比target小就列数加一
function Find(target, array)
{
if(array.length==0||array==undefined||array[0].length==0)
return false;
let rows=array.length;
let cols=array[0].length;
let row=0;
let col=cols-1;
while(row<rows&&col>=0){
if(array[row][col]==target)
return true;
if(array[row][col]>target)
col--;
if(array[row][col]<target)
row++;
}
}
替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
function replaceSpace(str)
{
return str.replace(/ /g,'%20')
}
从头到尾打印链表
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function printListFromTailToHead(head)
{
if(head==undefined) { //判断链表是否为空
return 0;
} else{
var arr=new Array(); // 新建一个数组,用于存放链表中的数值
var curr=head; // 创立一个指针,遍历链表
while(curr){
arr.push(curr.val);
curr=curr.next;
}
return arr.reverse();
}
}
重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
// 前序是根 左 右 在前序中找根
// 中序是左 根 右 在中序中找左右子树
// 在左右子树中以同样的方法找根和左右子树
// 知道遍历到某个子树的左右子树长度为0停止
function reConstructBinaryTree(pre, vin)
{
// write code here
if(pre.length==0&&vin.length==0) {
return null;
}
var index = vin.indexOf(pre[0]); // 返回根节点在中序遍历中的位置
var left = vin.slice(0,index); // 以根节点为界限找出左子树
var right = vin.slice(index+1); // 以根节点为界限找出右子树
var root=new TreeNode(pre[0]); // 新建二叉树
root.left=reConstructBinaryTree(pre.slice(1,index+1),left); // 运用递归
root.right=reConstructBinaryTree(pre.slice(index+1),right);
return root;
}
用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
var stack1=new Array();
var stack2=new Array();
//栈的特点是后进先出,队列的特点是先进先出
function push(node)
{
stack1.push(node); // 先进
}
function pop()
{
var temp=stack1.pop();
while(temp){ // stack1中先入的的数在stack2中的顶部
stack2.push(temp);
temp=stack1.pop();
}
var result=stack2.pop(); // 此时Stack2中顶部的数已经弹出
temp=stack2.pop();
while(temp){ // 将Stack2 中的数再依次压入stack1中
stack1.push(temp);
temp=stack2.pop();
}
return result;
}
旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
function minNumberInRotateArray(rotateArray)
{
if(rotateArray.length==0){
return 0
}
//其中第一个参数null,这个是因为没有对象去调用这个方法,所以直接传递null过去
return Math.min.apply(null,rotateArray);
}
斐波那契数列
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
// 斐波那契数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144........
// 从第3项开始,每一项都等于前两项之和
function Fibonacci(n)
{
if(n<0||n>39){
return;
}
if(n==0){
return 0;
}
if(n==1){
return 1;
}
var fone=0;
var ftwo=1;
var fn=0;
for(var i=2;i<=n;i++){
fn=fone+ftwo;
fone=ftwo;
ftwo=fn;
}
return fn;
}
跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
// 如果只有1级台阶,那显然只有一种跳法。
// 如果有2级台阶,那就有两种跳法:一种是分两次跳,每次跳1级;另一种就是一次跳2级。
// f(1)=1 f(2)=2 f(3)=3 f(4)=5 f(n)=f(n-1)+f(n-2)
// 用到递归
function jumpFloor(number)
{
// write code here
if(number==1){
return 1;
}
if(number==2){
return 2;
}
if(number<0){
return 0;
}
var jn=jumpFloor(number-1)+jumpFloor(number-2);
return jn;
}
变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
// 如果只有一层台阶,有一种跳法
// 如果有两层台阶,有两种跳法
// 如果有三层台阶,有四种跳法
// 当n>1时,第一次跳有n种选择,第二次跳有n-1种选择
// f(n)=f(n-1)+f(n-2)+...+f(0)
// f(n-1)=f(n-2)+f(n-3)+...+f(0)
// 两式相减f(n)=2*f(n-1)
function jumpFloorII(number)
{
// write code here
if(number == 0){
return 0;
}
if(number == 1){
return 1;
}
var fn=jumpFloorII(number-1)*2
return fn;
}
矩形覆盖
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
// 类似菲波那切数列
function rectCover(number)
{
// write code here
if(number==0){
return 0;
}
if(number==1){
return 1;
}
if(number==2){
return 2;
}
var f=rectCover(number-1)+rectCover(number-2);
return f;
}
二进制中1的个数
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
function NumberOf1(n)
{
// write code here
var num=0;
var target=1;
if(n==0){
return 0;
}
if(n!=0){
// console.log(target);
for(var i=0;i<32;i++){ //计算机中将整数按32位二进制存储
if((n>>>i&1)==1){ //因为分为正负数 所以采用无符号右移与1相与
num++;
}
}
return num;
// console.log(num);
}
}
数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
//将指数转换成二进制 按位进行运算
function Power(base, exponent)
{
// write code here
var res=1.0;
var n;
if(exponent>0){ //指数大于0
n=exponent;
}else if(exponent<0){ //指数小于0
if (!base) throw new Error('分母不能为0');
n=-exponent;
} else{
return 1; //指数等于0时结果永远是1
}
while(n){
if(n&1) //将指数转换成二进制数
res=res*base;
base=base*base;
n>>=1; //右移 以便判断指数相应位数是否为1 n=n>>1;
}
return exponent>0?res:1/res; //指数为正直接返回结果 指数为负返回结果的倒数
}
调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
// 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
// 所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
function reOrderArray(array)
{
// write code here
var newarray=[];
var ji=0; //奇数索引
var ou=0; //偶数索引
for(var i=0;i<array.length;i++){ //因为奇数位于前半部分,所以第一遍遍历数组找出数组中奇数的个数
if(array[i]%2==1){
ou++; //第一个偶数的位置
}
}
for(var j=0;j<array.length;j++){
if(array[j]%2==1){
newarray[ji]=array[j];
ji++;
}
else{
newarray[ou]=array[j];
ou++;
}
}
return newarray;
}
链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
/* function ListNode(x){
this.val = x;
this.next = null;
}*/
// 设置两个指针 pNode1 和 pNode2 两个指针相距 k-1 个距离
// pNode2先跑k个结点 pNode1跑到第一个结点
// 当pNode2的下一个节点为空 此时的pNode1指向倒数第k个结点
function FindKthToTail(head, k) {
if (head === null || k <= 0) return null;
let pNode1 = head,
pNode2 = head;
//先让pNode2跑k个结点
while (--k) {
if (pNode2.next !== null) {
pNode2 = pNode2.next;
} else {
return null;
}
}
// 判断pNode2下一个节点是否为空
while (pNode2.next !== null) {
pNode1 = pNode1.next;
pNode2 = pNode2.next;
}
return pNode1;
}
来源:CSDN
作者:陈小梓forever
链接:https://blog.csdn.net/weixin_43916694/article/details/103987848