剑指offer在线编程(二)

 

1、题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
答案:

 

function Power(base, exponent)
{
	return Math.pow(base, exponent);
}

说明:JS内置Math对象的pow方法即可 !
2、题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
答案:

function reOrderArray(array)
{
    var pre=[];
    var next=[];
    for(var i=0;i<array.length;i++){
        if(array[i]%2==1){
            pre.push(array[i]);
        }else{
            next.push(array[i]);
        }
    }
    return pre.concat(next);
}

3、题目描述
输入一个链表,输出该链表中倒数第k个结点。
答案:

function ListNode(x){
    this.val = x;
    this.next = null;
}
function FindKthToTail(head, k)
{	
    var arr=[];
    while(head){
        arr.unshift(head);
        head=head.next;
    }
    return arr[k-1];
}

4、题目描述
输入一个链表,反转链表后,输出链表的所有元素。
答案:

function ListNode(x){
    this.val = x;
    this.next = null;
}
function ReverseList(pHead)
{
    var p,temp=null;
    while(pHead){
        temp=pHead.next;
        pHead.next=p;
        p=pHead;
        pHead=temp;
    }
    return p;
}

5、题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
答案:

function ListNode(x){
    this.val = x;
    this.next = null;
}
function Merge(pHead1, pHead2)
{
    if (pHead1 == null || pHead2 == null) {
        return pHead1 || pHead2;
    }
    var head = null;
    if (pHead1.val < pHead2.val) {
        head = pHead1;
        head.next = Merge(pHead2,pHead1.next)
    }
    else {
        head = pHead2;
        head.next = Merge(pHead1, pHead2.next);
    }
    return head;
}

说明:递归,重点!!!
6、题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
答案:

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
function HasSubtree(pRoot1, pRoot2)
{	
    var flag=false;
    // 当树1和树2都不为空时进行比较
    if (pRoot1!=null&&pRoot2!=null) {
    	//如果他们的根节点相同
    	if (pRoot1.val==pRoot2.val) {
    		flag=compareSubTree(pRoot1,pRoot2);
    	}
    	//如果不相同,以树1的当前根节点的左孩子为根节点比较
    	if (!flag) {
    		flag=HasSubtree(pRoot1.left, pRoot2);
    	}
    	//如果仍不相同,以树1的当前根节点的右孩子为根节点比较
    	if (!flag) {
    		flag=HasSubtree(pRoot1.right, pRoot2);
    	}
    }
    return flag;
}
function compareSubTree(root1,root2){
	//如果此时树2为空,说明树2已经遍历完了,且都对的上
	if (root2==null) {
		return true;
	}
	//如果此时树2不为空,树1为空,说明树2不是树1的子树
	if (root2!=null&&root1==null) {
		return false;
	}
	//如果两树都不为空,但其中有一个点对不上
	if (root1.val!=root2.val) {
		return false;
	}
	//如果当前两树的根节点能对上,就去子树中比较
	return compareSubTree(root1.left,root2.left)&&compareSubTree(root1.right,root2.right);
}

7、题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树 
       8
      /  \
     6   10
    / \  / \
    5  7 9 11
    镜像二叉树
       8
      /  \
     10   6
    / \  / \
    11 9 7  5
答案:

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
function Mirror(root)
{
    if(root==null){
        return null;
    }else{
        var left=Mirror(root.right);
        var right=Mirror(root.left);
        root.left=left;
        root.right=right;
        return root;
    }
}

思路:每一个子二叉树左右子树交换即可。
8、题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
答案:

function printMatrix(matrix)
{
    var row = matrix.length;
   var col = matrix[0].length;
   var i = 0;
   var j = 0;
   var dir = 1;
   var circle = 0; //循环的圈数
   var result = [];
   while(result.length<row*col){
       switch(dir) {
           case 1: //从左至右
               if(j< col-circle) {
                   result.push(matrix[i][j]);
                   j++;
               } else {
                   j--;
                   i++;
                   dir = 2;
               }
               break;
           case 2: //从上至下
                   if(i < row -circle) {
                     result.push(matrix[i][j]);
                     i++;
                } else {
                   i--;
                   j--;
                  dir = 3;
               }
               break;
           case 3: //从右至左
               if(j>=circle) {
                   result.push(matrix[i][j]);
                   j--;
               } else {
                   j++;
                   i--;
                   dir = 4;
               }
               break;
           case 4://从下至上
               if(i > circle) {
                   result.push(matrix[i][j]);
                   i--;
               } else {
                   i++;
                   j++;
                   circle++; //第一圈结束,第二圈开始
                   dir = 1;
               }
               break;
       }
   }
    return result;
}

9、题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
答案:

var stack=[];
function push(node)
{
    stack.push(node);
    return stack;
}
function pop()
{
    stack.pop();
    return stack;
}
function top()
{
    return stack.length-1;
}
function min()
{
    return Math.min(...stack);
}

10、题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
答案:

function IsPopOrder(pushV, popV){
   var j=0;
   var stack=[];
   for(var i=0;i<pushV.length;i++){
   	stack.push(pushV[i]);
   	for(;j<popV.length;j++){
   		if (stack.length>0) {
   			if (stack[stack.length-1]==popV[j]) {
   				stack.pop();
   			}else{
   				break;
   			}
   		}else{
   			break;
   		}
   	}
   }
   return stack.length==0?true:false;
}

思路:用一个临时栈来存储压入栈的元素,如果当前栈顶元素等于popV[j],则删除当前栈顶所在元素,并popV后移一位,...,如此循环。判断临时栈是否为空,空则true,否则false。
11、题目描述
从上往下打印出二叉树的每个节点的值,同层节点从左至右打印。
答案:

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
function PrintFromTopToBottom(root)
{
    var arr=[];
    var result=[];
    if(root==null){
        return [];
    }
    arr.push(root);
    while(arr.length){
        var node=arr.shift();
        result.push(node.val);
        if(node.left){
            arr.push(node.left);
        }
        if(node.right){
            arr.push(node.right);
        }
    }
    return result;
}

12、题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
答案:

function VerifySquenceOfBST(arr)
{
    if(arr.length==0){
        return false;
    }
    return IsVerify(arr);
}
function IsVerify(arr){
    if(arr.length<3){
        return true;
    }
    var root=arr[arr.length-1];
    var left=[],right=[];
    for(var i=0;i<arr.length;i++){
        if(arr[i]>root){
            right=arr.slice(i,arr.length-1);
            break;
        }else{
            left.push(arr[i]);
        }
    }
    if(right.length==0){
        return true;
    }
    for(var i=0;i<right.length;i++){
        if(right[i]<root){
            return false;
        }
    }
    return IsVerify(left)&&IsVerify(right);
}

思路:
二叉搜索树的特点:左子树的值都小于等于根,右子树的值都大于等于根;
后序遍历:左右根;
当整数序列的长度部位0时:得到根(序列最后的值),遍历寻找左子树和右子树,递归整个过程;递归终止条件:数组的长度小于3时,返回true。
13、题目描述
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
答案:

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
function FindPath(root, expectNumber)
{
    if(root==null||expectNumber<=0||expectNumber<root.val){
        return false;
    }else{
        var path=[],stack=[];
        return treePath(root,expectNumber,path,stack);
    }
}
function treePath(root,number,path,stack){
    stack.push(root.val);
    if(root.val==number&&root.left==null&&root.right==null){
        path.push(stack.slice(0));
    }else{
        if(root.left!=null){
            treePath(root.left,number-root.val,path,stack);
        }
        if(root.right!=null){
            treePath(root.right,number-root.val,path,stack);
        }
    }
    stack.pop();
    return path;
}

思路:在树不为空且当前值大于当前树根的值时,将树根的值暂存在栈数组中,如果树根的值等于给定值且左右子树都为空,则将栈数组中的值作为路径复制到路径数组中;否则左右子树不为空时分别递归调用这个过程,且此时给定值应要减去根节点的值。如果左右子树都为空但当前根的值不等于给定值,则该路径不满足条件,清空栈数组的值。
14、题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
答案:

function RandomListNode(x){
    this.label = x;
    this.next = null;
    this.random = null;
}
function Clone(pHead)
{
    if(pHead==null){
        return null;
    }
    var head=new RandomListNode(pHead.val);
    head.label=pHead.label;
    head.random=pHead.random;
    head.next=Clone(pHead.next);
    return head;
}

15、题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解题思路:
1.将左子树构造成双链表,并返回链表头节点。
2.定位至左子树双链表最后一个节点。
3.如果左子树链表不为空的话,将当前root追加到左子树链表。
4.将右子树构造成双链表,并返回链表头节点。
5.如果右子树链表不为空的话,将该链表追加到root节点之后。
6.根据左子树链表是否为空确定返回的节点。
答案:

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
function Convert(root)
{
    if(root==null){
        return null;
    }
    if(root.left==null&&root.right==null){
        return root;
    }
    // 1.将左子树构造成双链表,并返回链表头节点
    var left = Convert(root.left);
    var p = left;
    // 2.定位至左子树双链表最后一个节点
    while(p!=null&&p.right!=null){
        p = p.right;
    }
    // 3.如果左子树链表不为空的话,将当前root追加到左子树链表
    if(left!=null){
        p.right = root;
        root.left = p;
    }
    // 4.将右子树构造成双链表,并返回链表头节点
    var right = Convert(root.right);
    // 5.如果右子树链表不为空的话,将该链表追加到root节点之后
    if(right!=null){
        right.left = root;
        root.right = right;
    }
    return left!=null?left:root;
}

16、题目描述【全排列问题】
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
答案:

function Permutation(str)
{
    if (str.length <= 0){
        return [];
    }
    var tempStr = '';
    var res = [];
    var arr = str.split('');
    findString(arr,tempStr,res);
    return res;
}
function findString(arr,tempStr,res) {
    if (arr.length == 0)
        res.push(tempStr);
    else {
        var isUsed = {}; //标志当前字符是否重复
        for (var i=0; i<arr.length; i++) {
            if (!isUsed[arr[i]]) {
                var temp = arr.splice(i, 1)[0]; //每次截取一个字符
                tempStr += temp;
                findString(arr,tempStr,res);
                arr.splice(i,0,temp); //每次添加一个字符
                tempStr = tempStr.slice(0, tempStr.length -1);
                isUsed[temp] = true;
            }
        }
    }
}

思路:字符的交换。
17、题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
答案:

function MoreThanHalfNum_Solution(numbers){
	let obj={};
	for(let i=0;i<numbers.length;i++){
		if (!obj[numbers[i]]) {
			obj[numbers[i]]=[numbers[i]];
		}else{
			obj[numbers[i]].push(numbers[i]);
		}
	}
	for(let attr in obj){
		if (obj[attr].length>numbers.length/2) {
			return attr;
		}
	}
	return 0;
}

18、题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
答案:

function GetLeastNumbers_Solution(input, k){
	if (k<=input.length) {
		input.sort((item1,item2)=>item1-item2);
		return input.slice(0,k);
	}else{
		return [];
	}
}

19、题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?
例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)
答案:

function FindGreatestSumOfSubArray(array){
	if (array.length==0) {
		return false;
	}
	var max=array[0]; //注意此处不能为0,避免全为负数的情况
	var temp=array[0];
	for(var i=1;i<array.length;i++){
		temp=temp>0?temp+array[i]:array[i];
		max=max>temp?max:temp;
	}
	return max;
}

思路:用一个临时变量累加数组项,如果临时值小于0,则从当前项开始重新累加;
20、题目描述
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
答案:

function NumberOf1Between1AndN_Solution(n){
	var sum=0;
	for(var i=1;i<=n;i++){
		var match=i.toString().match(/1/g);
		if (match) {
			sum+=match.length;
		}
	}
	return sum;
}

思路:每个数转换成字符串,再利用正则进行每个字符串的全局匹配;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明致成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值