前端面试算法集合

问题1:给定一个数组a和一个长度值l,生成一个指定长度值为l的新数组b,要求b中的每一个元素都是从a中随机获取的,且数组元素不可重复。

function generate(a,l){
if(a.length < l) return '老数组长度不足!';
/*a长度可能超出,可以生成新数组后截取长度为l的赋值给b,也可以生成为l的b(这里选第二种)*/
var i=0, tmp=[], b=[];
// 每次获取a的一个随机元素,同时将
while(i<l && tmp.length<=a.length) {
var random = Math.floor(Math.random()*(a.length));
if(tmp.indexOf(random) == -1) { // 判断随机元素是否已经使用过,未使用则放入临时数组记录
tmp.push(random);
var number = a[random]; // 获取数组a中的随机数
console.log(random+"..."+number);
if(b.indexOf(number) == -1) { //部分IE不支持indexOf请自行解决。也可以使用jquery的$.inArray方法,总之就是不重复扔进b
b.push(number);
i++; // 新随机数时+1
}
}
}
if(b.length==l) return b;
else return '新数组长度不足: '+ b;
}

// 测试
var a=[3,2,1,6,3,9,2,5];
generate(a, 5)

问题2:使用js写一个栈结构。然后如何让这个栈满足两个调用者同时使用的要求?

function Stack() {
  this.dataStore = [];
  this.top = 0;//栈顶元素的位置
  this.push = push;
  this.pop = pop;
  this.peek = peek;
  this.length=length;
  this.clear=clear;
}

function push(element) {//进栈
   this.dataStore[this.top++] = element;
}

function pop() {//出栈
  return this.dataStore[--this.top];
}

function peek() {//栈顶元素
  return this.dataStore[this.top-1];
}

function length() {
  return this.top;
}

function clear() {
  this.top = 0;
}

//测试栈的实现
var s= new Stack();
s.push("D");
s.push("R");
s.push("B");
console.log(s.length());
console.log(s.peek());
console.log(s.clear());
console.log(s.length());

问题3:找出数组中只出现一次的元素

 function num(arr){
        var str=arr.join(''); 
        var res=[];
        for(var i=0;i<str.length;i++){           
            var num=str.split(str[i]).length-1;
            if(num===1){
                res.push(str[i]);
            }
        }

        return res;

     }
     var arr=[1,2,1,4,3,3];
     console.log(num(arr));

问题4:现在对于给定的一个字符串s,请计算出字典序最大的s的子序列。

function max(str){
        //字典序从小到大:abcdefg......
        var arr=str.split('');
        var res=[arr[arr.length-1]];//字符串最后一个元素肯定符合条件
        for(var i=arr.length-2;i>=0;i--){//从倒数第二个元素开始,找单调递增的元素
            if(arr[i]>=res[0]){
                res.unshift(arr[i]);//找到符合的直接加入到res中
            }
        }
        return  res.join('');

     }

     var str='abddaa';
     console.log(max(str));

 

问题6:把一棵二叉树变成它的镜像二叉树

function Mirror(root){
            if(root==null){//当一开始根节是空的时候,返回false
                return false;
            }
            if(root.left ==null && root.right ==null){//当只有一个根节点时返回false
                return false;

            }
            //第三种情况:当左右子树不为空的时候,交互左右子树节点
            var temp=root.left;
            root.left=root.right;
            root.right=temp;
            if(root.left!=null){//递归遍历左子树
                Mirror(root.left);
            }
            if(root.right!=null){//递归遍历右子树
                Mirror(root.right);
            }
        }

问题7:顺时针打印矩阵

function printMatrix(matrix)
{
    // write code here
        var row1 = 0;
        var row2 = matrix.length-1;
        var col1 = 0;
        var col2 = matrix[0].length-1;
        var rowflag = 1;
        var colflag = 1;
       var list=[];
        while(row2>=row1 && col2>=col1){
            if(rowflag == 1){
                for(var i=col1; i<=col2; i++)
                    list.push(matrix[row1][i]);
                row1++;
            }
            if(colflag == 1){
                for(var i=row1; i<=row2; i++)
                    list.push(matrix[i][col2]);
                col2--;
            }
            if(rowflag == -1){
                for(var i=col2; i>=col1; i--)
                    list.push(matrix[row2][i]);
                row2--;
            }
            if(colflag == -1){
                for(var i=row2; i>=row1; i--)
                    list.push(matrix[i][col1]);
                col1++;
            }
            rowflag = rowflag*(-1);
            colflag = colflag*(-1);
        }
        
        return list;
 
}

问题8:Fibinacc数列

function Fibnacci(n){
            var res=[0,1];
            if(n<2){
                return res[n];
            }
            var fib1=0;
            var fib2=1;
            var fibn=0;
            for(var i=2;i<=n;i++){
                fibn=fib1+fib2;
                fib1=fib2;
                fib2=fibn;
            }
            return fibn;

        }
function jumpFloor(number)
{
    if(number ===0){
        return 0;
    }
    if(number===1){
        return 1;
}
    if(number ===2){
        return 2;
    }
    var one = 1;
    var two = 2;
    var num = 0;
    for(let i=3;i<=number;i++){
        num = one + two;
        one = two;
        two = num;
         
    }
    return num
}

问题9:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

function Find(target, array) {
//从最右上角开始确定一个点开始比较
  let i = 0;
  let j = array[i].length - 1;//将最右边的列作为定点
  while (i < array.length && j >= 0) {
    if (array[i][j] < target) {
      i++;
    } else if (array[i][j] > target) {
      j--;
    } else {
      return true;
    }
  }
  return false;
}

问题10:数组中出现次数超过一半的元素

方法1:

function MoreThanHalfNum_Solution(numbers)
{
    // write code here
    if(numbers==null){
        return null;
    }    
        var string=numbers.join('');
        var len=Math.floor(numbers.length/2);
        for(var i=0;i<numbers.length;i++){
           var num=string.split(numbers[i]).length-1;
           if(num>len){
              return numbers[i];
               break;
           }
        }    
        return 0;
}

方法2:

function MoreThanHalfNum_Solution(numbers)
{
    // write code here
     var len=numbers.length;
    if(len==0)return 0;
    var num=numbers[0];
        count=1;
    for(var i=0;i<len;i++){
        if(num==numbers[i]){
            count++;
        }else{
            count--;
        }
        if(count==0){
            num=numbers[i];
            count=1;
        }
    }
    count=0;
    for(var i=0;i<len;i++){
        if(numbers[i]==num)count++;
    }
    if(count*2>len)return num;
    return 0;
}

问题11:从尾到头打印链表

//借助两个数组arr1和arr2,arr1用来保存按链表顺序压栈,arr2用来保存arr1出栈的元素序列
function printListFromTailToHead(head)
{
    // write code here
    if(head==null){
        return [];
    }
    var arr1=[];
    var arr2=[];
    var p=head;
    while(p!=null){//首先将元素压入栈
        arr1.push(p.val);
        p=p.next;
    };
    while(arr1.length>0){//将arr1里面的元素依次pop到arr2中
        arr2.push(arr1.pop());
    }
    return arr2;    
}

问题12:重建二叉树

function reConstructBinaryTree(pre, vin)
{
    // write code here
    var root=pre[0];
    if(pre.length==0||vin.length==0){
        return false;
    }
    for(var i=0;i<vin.length-1;i++){
        if(vin[i]===pre[0]){
           //找左子树的前序序列和中序序列
            var leftPre=[].concat(pre.splice(1,i+1));
            var leftIn=[].concat(vin.splice(0,i));
            //递归遍历左子树,并将左子树加到根节点上
            root.left=reConstructBinaryTree(leftPre,leftIn);
            //找右子树的前序序列和中序序列
            var rightPre=[].concat(pre.splice(pre.length-i,pre.length));
            var rightIn=[].concat(vin.splice(i+1,vin.length));
            //递归遍历右子树,并将右子树加到根节点上
            root.right=reConstructBinaryTree(rightPre,rightIn);
        }
    }
   return  root;    
}

问题13:旋转数组的最小数字

function minNumberInRotateArray(rotateArray)
{
    // write code here
     if (array == null || array.length == 0) {//当输入的是0或者是空的时候
            return 0;
        }
        if (array.length == 1 || array[array.length - 1] > array[0]) {
   //当输入的是一个元素或者是单调递增的
            return array[0];
        }
         
        var start = 0;
        var end = array.length - 1;
         
        while (start < end) {
            var mid = parseInt((end - start) / 2 + start);
            if (array[mid] == array[end]) {
                end--;
            } else if (array[mid] < array[end]){
                end = mid;
            } else {
                start = mid + 1;
            }
        }
         
        return array[start];
}

问题14:输入一个链表,输出该链表中倒数第k个结点。

方法一:

function FindKthToTail(head, k)
{
    // write code here
    if(head==null){
        return null;
    }
    var res=[];
    var len=0;
    var p=head;
    while(p!=null){
        res.push(p);
        p=p.next;
    }
    return res[res.length-k];    
}

方法二:

function FindKthToTail(head, k) {
    // write code here 
    if( head==null|| k==0 ){
        return false; 
    } 
    var p1=head;
    var p2=null;
    for( var i=0;i<k-1;i++){ 
        if(p1.next!=null){ 
            p1=p1.next; 
        }else{
            return null;
        } 
    
    } 
    p2=head; 
    while( p1.next!=null){
        p1=p1.next;
        p2=p2.next;
    }
    return p2;
}

问题15:反转链表

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function ReverseList(pHead)
{
    // write code here
    if(pHead==null){
        return null;
    }
    var arr=[];
    var p1=pHead;
    
    while(p1!=null){
        arr.push(p1);
        p1=p1.next;       
        //数组里面装的是节点类型的元素       
    }
    //console.log(arr.length);
    var p2Head=arr.pop();
    var p2=p2Head;
    var pre=p2Head;//用来重新连接的指针
    
    while(arr.length>0){
        p2=arr.pop();
        pre.next=p2;
        pre=p2;
    }
   pre.next=null;//最后给最后一个元素的next置为空
    return p2Head; 
}
module.exports = {
    ReverseList : ReverseList
};

问题16:合并两个有序链表

function ListNode(x){
    this.val = x;
    this.next = null;
}
function Merge(pHead1, pHead2)
{
    // write code here
    var p1=pHead1;
    var p2=pHead2;
    var pHead3=new ListNode(-1);//自己定义一个头结点
    var p3=pHead3;
    while(p1!=null && p2!=null){        
        if(p1.val<=p2.val){
            p3.next=p1;
            p3=p1;
            p1=p1.next;
            continue;//如果走到最后一个,不能再进行下面的判断,因为没有val值
        }
        if(p1.val>p2.val){
            p3.next=p2;
            p3=p2;
            p2=p2.next;
        }
    }
        while(p1!=null){
           p3.next=p1;
            p3=p1;
            p1=p1.next;
        }
        while(p2!=null){
            p3.next=p2;
            p3=p2;
            p2=p2.next;
            
        }
    return pHead3.next;
    
}
module.exports = {
    Merge : Merge
};

问题17:操作给定的二叉树,将其变换为源二叉树的镜像。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function Mirror(root)
{
    // write code here
    if(root==null){
        return null;
    }
    if(root.left==null&&root.right==null){
        return root;
    }
//前序遍历    用后序遍历也可以
    var temp=root.left;
    root.left=root.right;
    root.right=temp;
    Mirror(root.left);
    Mirror(root.right);  
    
}

问题18:从上往下层次打印二叉树节点

  解题思路:利用一个队列进行层次遍历,先把一个节点放到队列中,然后再利用这个结点把它的左子结点和右子结点放到队列中;然后再把该节点放到打印数组中;循环的条件是队列不为空

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function PrintFromTopToBottom(root)
{
    // write code here
     // write code here层序遍历,是先判断元素的左右子树,再将头节点出队列
    var queue=[];
    var res=[];
    if(root!=null){//先判断第一个不为空时把节点加入到队列中
        queue.push(root);
    }
    while(queue.length!=0){//开始判断一下队列的元素
        var node=queue.shift();
        if(node.left!=null){//先判断下有没有左右子树,有的话先把左右子树节点加入到队列
            queue.push(node.left);
        }
        if(node.right!=null){
            queue.push(node.right);
        } 
        res.push(node.val);
    }
    return res;
}
module.exports = {
    PrintFromTopToBottom : PrintFromTopToBottom
};

问题19 :和为S的两个数字

function FindNumbersWithSum(array, sum)
{
    // write code here
       if(array==null){
            return null;
        }
        var left=0;
        var right=array.length-1;
        var curNum=0;
        var mulSum;
        var result=[];
        var min=Number.POSITIVE_INFINITY;
        var index1;
        var index2;
        var flag=false;
        while(left<right){
            
            curNum=array[left]+array[right];
            if(curNum==sum){
                flag=true;
                mulSum=array[left]*array[right];
                if(min>mulSum){
                min=mulSum;
                index1=left;
                index2=right;
            }
                left++;
                right--;
            }
            if(curNum<sum){ 
                left++;
            }
            if(curNum>sum){
                right--;
            }            
        }
    if(flag==true){
              result.push(array[index1]);
            result.push(array[index2]);
       
        return result;
    }
    return [];
    
    
}

问题20:和为S的连续正数子序列

function FindNumbersWithSum(array, sum)
{
    // write code here
       if(array==null){
            return null;
        }
        var left=0;
        var right=array.length-1;
        var curNum=0;
        var mulSum;
        var result=[];
        var min=Number.POSITIVE_INFINITY;
        var index1;
        var index2;
        var flag=false;
        while(left<right){
            
            curNum=array[left]+array[right];
            if(curNum==sum){
                flag=true;
                mulSum=array[left]*array[right];
                if(min>mulSum){
                min=mulSum;
                index1=left;
                index2=right;
            }
                left++;
                right--;
            }
            if(curNum<sum){ 
                left++;
            }
            if(curNum>sum){
                right--;
            }            
        }
    if(flag==true){
              result.push(array[index1]);
            result.push(array[index2]);
       
        return result;
    }
    return [];
    
    
}

问题21:将数组按层次展开

var list = [1,2,[3,4],[5,6,[7,8],9],10,11]
		var res = [];
		function flatten(list, depth){
			if(depth == 0){
				for(var i = 0; i<list.length; i++){
					res.push(list[i]);
				}
				return;
			}
			for(var i = 0; i<list.length; i++){
				if(list[i] instanceof Array){
					flatten(list[i], depth - 1);
				}else{
					res.push(list[i]);
				}
			}
			return res;
		}

		console.log(flatten(list, 1));
		
		res = [];
		console.log(flatten(list, 2));

问题22:数组去重

  方法1:先排序,然后将第一个元素先放进结果数组中,从第二个起循环遍历数组,每次都和结果数组的最后一个元素比较。

    function del(arr){
        var arr=arr.sort();
        
        var res=[arr[0]];//把第一个元素取出来
        for(var i=0;i<arr.length;i++){
            if(arr[i]!=res[res.length-1]){//每次都和结果数组中的元素作比较
                res.push(arr[i]);
            }
        }
        return res;
    }
     var arr=[1,3,2,4,2,5,2,5];
     console.log(del(arr));

方法2:使用indexof方法    

function del(arr){
        var res=[];
        for(var i=0;i<arr.length;i++){
            if(res.indexOf(arr[i])==-1){
                res.push(arr[i]);
            }
        }

        return res;
    }

方法3:使用set()方法

    function quchong(arr){
        const s=new Set(arr);
        console.log(s);
    }
     var arr=[1,3,2,4,2,5,2,5];
     quchong(arr);

问题23:判断单链表里是否有环,以及其入口节点

   1判断是否有环    

<script type="text/javascript">  
      const slow=pHead;//慢指针走一步
      const fast=pHead;//
      while(slow!=null&fast.next!=null){//没有环的时候,快指针有可能跳出链表,所以让fast的next不为空
        fast=fast.next.next;
        slow=slow.next;
        if(fast==slow){
            return true;
        }
      }
      return false;
     </script>

  2,找环的入口

     原理:从链表起点head开始到入口点的距离a,与从slow和fast的相遇点到入口点的距离相等。(别人推导出来的)

    <script type="text/javascript">  
      const slow=pHead;//慢指针走一步
      const fast=pHead;//
      while(slow!=null && fast.next!=null){
           fast=fast.next.next;
           slow=slow.next;
           if(slow==fast)  break;
      }
      if(slow==null || fast.next==null) return null;//表示链表没有环
      const p1=pHead;//一个指向链表的起点
      const p2=slow;//一个指向快慢指针相遇点
      while(p1!=p2){
        p1=p1.next;
        p2=p2.next;
      }
      return p1;//p1和p2走了一样的距离并相遇时便是入口点
     </script>

3 如果存在环,求环上的节点数

记录下相遇时的节点,并且存入临时变量temp中,然后慢指针继续往下走slow=slow.next,一直到slow=temp,此时经过的步数就是环的长度。

     <script type="text/javascript">  
      const slow=pHead;//慢指针走一步
      const fast=pHead;//
      const step=1;
      while(slow!=null && fast.next!=null){
           fast=fast.next.next;
           slow=slow.next;
           if(fast==slow){
            const temp=slow;//找到了相遇点,并且把它记录下来
            slow=slow.next;
            break;
           }
      }
      while(slow!=temp){//slow一直走到temp的位置,slow从相遇点开始走的步数就是环的长度
         slow=slow.next;
         step++;
     }
     return step;
     </script>

4 如果存在环,求出链表的长度

  解决思路:链表的长度=起点到入口的距离+环的长度

5 求出一个环上距离任意一个节点最远的点

问题:构建乘积数组

将数组B分开,分成左下三角和右上三角;左下三角c[i]=c[i-1]*A[i-1].右上三角 D[i]=D[i+1]*A[i+1];

问题24:删除有序链表中重复的节点,重复节点都不保留,返回头指针。

    用当前cur指针和pre前驱指针,当两者相邻的时候说明cur还没有找到重复元素,不相邻的时候说明pre和cur之间有了部分相同的元素。

function ListNode(x){
    this.val = x;
    this.next = null;
}
function deleteDuplication(pHead)
{
    // write code here
    if(pHead==null){
        return null;
    }
    var node=new ListNode(-1);
    node.next=pHead;
    var pre=node;
    var cur=node.next;
    while(cur!=null){
        while(cur.next!=null && cur.val==cur.next.val){//一定要注意cur.next!=null
            cur=cur.next;
        }
        if(pre.next!=cur){//cur找到重复元素往后移动了,才不和Pre挨着了
            pre.next=cur.next;
            cur=cur.next;
        }else{//当还没遇到重复元素时,既pre 和cur还挨着的时候
            pre=cur;//只有先让pre移动到cur,cur再移动,才能保证pre永远比cur慢一步
            cur=cur.next;            
        }
    }
    return  node.next;
    
}

问题25:二叉树的下一个结点。给定一课二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。

该题的解题思路就是:

分两种情况:1.该节点有右子树,则右子树的最最左结点是所要找的节点

                      2.该节点没有右子树,则一直往上找,直到找到一个结点是其父结点的左子结点,则该父结点就是所要找的节点

/*function TreeLinkNode(x){
    this.val = x;
    this.left = null;
    this.right = null;
    this.next = null;
}*/
function GetNext(pNode)
{
    // write code here
    //分三种情况:
    //1.当该节点有右子树,则右子树的最左子节点是所要找的节点
    //2.当该节点没有右子树,则找当前节点是其父节点的左子结点的节点
   
    if(pNode==null){
        return null;
    }
    if(pNode.right!=null){//情况1
        var pNode=pNode.right;
        while(pNode.left!=null){
            pNode=pNode.left;
        }
        return pNode;
    }
    while(pNode.next!=null){//情况2
        if(pNode.next.left==pNode){
            return pNode.next;
        }
        pNode=pNode.next;
    }
   }

问题26:实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

   

function isSymmetrical2(root1,root2){
    if(root1 == null && root2 == null){
        return true;
    }
    if(root1 == null || root2 == null){
        return false;
    }
    if(root1.val != root2.val){
        return false;
    }
    return  isSymmetrical2(root1.left,root2.right) && isSymmetrical2(root1.right,root2.left); 
}
function isSymmetrical(pRoot)
{
    // write code here
    return isSymmetrical2(pRoot,pRoot);
}

问题27:按之字形状从上到下打印二叉树。第一行按从左到右的顺序打印,第二行按从右到左的顺序打印,接下来的依次交换

   解题思路:使用两个栈来操作,stack1用来暂存奇数行的节点,stack2用来暂存偶数行的节点。当奇数行的时候,将奇数行元素加入结果数组的同时,还把下一行的元素按照先左子节点后右子节点的顺序加入到stack2中;当偶数行的时候,将偶数行元素加入结果数组的同时,还把下一行的元素按照先右子节点后左子节点的顺序加入到stack1中;

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function Print(pRoot)
{
    // write code here
    var lists=new Array();//存放结果
    if(pRoot==null){
        return lists;
    }
    
    var stack1=[];//存放奇数行
    var stack2=[];//存放偶数行
    stack1.push(pRoot);
    var i=1;//层数
    while(stack1.length!=0 || stack2.length!=0){
        var list=new Array();
        if((i&1)==1){//当是奇数行的时候
            while(stack1.length!=0){
            var temp=stack1[stack1.length-1];//用一数组记录下,一直是从后往前push的
            list.push(temp.val);
            stack1.pop();
            if(temp.left!=null){
               //把下一行(偶数行)的数保存在stack2中,因为是从右往左,所以在栈中先添加左子节点
                stack2.push(temp.left);
            }
            if(temp.right!=null){
                stack2.push(temp.right);
            }
        }
        }else{//当是偶数行的时候
            while(stack2.length!=0){
                var temp=stack2[stack2.length-1];
                list.push(temp.val);
                stack2.pop();
                //因为奇数行是从左往右打印,所以在栈中先添加右子节点再添加左子节点
                if(temp.right!=null){
                    stack1.push(temp.right);
                }
                if(temp.left!=null){
                    stack1.push(temp.left);
                }
            }
        }
        i++;
        lists.push(list);       
        
    }   
    return lists;
    
}

问题28:从上到下把二叉树打印成多行。

解题思路: 在层序遍历+队列的基础上,判断每层的节点数;先把每层的节点放进数组中,然后再把这个数组放在结果数组中。 

function Print(pRoot)
{
    // write code here
    if(pRoot==null){
        return [];
    }
    var queue=[];
    var res=[];
    queue.push(pRoot);
    while(queue.length!=0){
        var len=queue.length;//一定要在这个地方标记一下queue的长度,以免queue添加的时候篡改
        var tempArr=[];//用来临时保存一行的元素
        for(var i=0;i<len;i++){
            var node = queue.shift();//会自动的减掉queue的长度
            tempArr.push(node.val);//将一行放在一个临时数组中
            if(node.left!=null){
                queue.push(node.left);
             }
            if(node.right!=null){
                queue.push(node.right);
             }
        }        
        res.push(tempArr);
    }   
    
    return res;
}

问题29 序列化一棵二叉树

  解题思路:先将一个棵树深度遍历(前序遍历)到一个数组,其中将'a’作为树的叶子节点;然后再前序遍历反序列化

 function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} 
let arr=[]
function Serialize(pRoot)
{
    // write code here
    if(pRoot!=null){//深度优先遍历
        arr.push(pRoot.val);
        Serialize(pRoot.left);
        Serialize(pRoot.right);         
    }else{
        arr.push('a');//把a当做叶子节点        
    }
    
}
function Deserialize()
{
    // write code here
    var root=null;
    if(arr.length<0){
        return null
    };//接上一种情况,当arr里没有元素的时候
    let node=arr.shift();
    if(typeof node == 'number'){
        root=new  TreeNode(node);//将摘下来的node传给一个树节点
        root.left=Deserialize();
        root.right=Deserialize();
        
    }
    return root;    
}

问题30  给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4。

  解题思路:中序遍历+计数。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function KthNode(pRoot, k)
{
    // write code here
     if(pRoot==null || k==0){
        return null;
    }
   function KthNodeCore(pRoot){//对这个函数进行递归
        let target = null;//目标值
        if(pRoot.left != null){ //中序遍历先遍历左子树
            target = KthNodeCore(pRoot.left, k);
        }
        if(target == null){//当左子树遍历不到的时候,遍历根节点
            if(k == 1){//k等于1说明找到了
                target = pRoot;
            }
            k--; 
        }
        if(target == null && pRoot.right != null){//当左子树和根都没有找到的话,遍历右子树
            target = KthNodeCore(pRoot.right, k);
        }
        return target;
    }
    return KthNodeCore(pRoot);
}

 问题:数组中重复的数字

由于数组里的所有数字都在0到n-1,也就是值也在数组的下标范围里。

我们可以这样做,通俗来讲,就是把数组中的每个值放到对应的下标的位置上。(数归其标)

  1. 把当前序列当成是一个下标和下标对应值是相同的数组;
  2. 遍历数组,判断当前位的值和下标是否相等: 2.1. 若相等,则遍历下一位; 2.2. 若不等,则将当前位置i上的元素和a[i]位置上的元素比较:若它们相等,则成功,即找到了重复的值!若不等,则将它们两交换。换完之后a[i]位置上的值和它的下标是对应的,但i位置上的元素和下标并不一定对应;重复2.2的操作,直到当前位置i的值也为i,将i向后移一位,再重复2.
function duplicate(numbers, duplication)
{
    // write code here
    //这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    //函数返回True/False
      for(var i=0;i<numbers.length;i++){
        while(i!=numbers[i]){//每次都是把元素放在它对应的位置
            if(numbers[i]==numbers[numbers[i]]){
                duplication[0]=numbers[i];
                return true;
            }
            var temp=numbers[i];
            numbers[i]=numbers[temp];
            numbers[temp]=temp;
        }
    }
    return false;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值