算法题---拼多多

一般会问笔试中的题****

(1)一个数二进制有多少个1

最简单的是转正二进制,循环判断1的个数

 public int NumberOf1(int n) {
       int count=0;
       String str = Integer.toBinaryString(n);
       for(int i=0;i<str.length();i++) {
    	   if(str.charAt(i)=='1') {
    		   count++;
    	   }
       }
       return count;
 }

但是还有更简单的方法,通过&运算符

public int NumberOf1(int n) {
       int count=0;
       while(n!=0){
           count++;
           n=n&(n-1);
       }
       return count;
}

思路:

如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。


2.判断一颗树是不是平衡二叉树

首先要会写求数高度的方法deep(TreeNode root)

然后获得该数的左右子树的高度,当高度差不大于1是,是平衡二叉树。

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root==null){
            return true;
        }else{
            int left=deep(root.left);
            int right=deep(root.right);
            if(left-right>1||right-left>1){
                return false;
            }else{
                return true;
            }
        }
    }
    public int deep(TreeNode root){
        if(root==null){
            return 0;
        }
        int left=deep(root.left);
        int right=deep(root.right);
        return Math.max(left+1,right+1);
    } 
}

3.二叉查找树BST的插入和查找

//树类
public class TreeNode {
	//节点值
	int val=0;
	//左子树
	TreeNode left=null;
	//右子树
	TreeNode right=null;
	//构造函数
	public TreeNode(int val){
	    this.val=val;
	}
}
//二叉搜索树
public class BST {
	//二叉树的构建,即根据数组构建
	public TreeNode creatBST(TreeNode root,int []datas) {
		root=null;
		int index=0;
		while(index<datas.length) {
			root=insertBST(root, datas[index]);
			index++;
		}
		return root;
	}
	//二叉树的插入
	public TreeNode insertBST(TreeNode root,int data) {
		if(root==null) {
			root=new TreeNode(data);
			return root;
		}
		//非递归方式
		TreeNode p=root;
		while(p!=null) {
			while(data<p.val) {
				if(p.left==null) {
					p.left=new TreeNode(data);
					return root;
				}
				p=p.left;
			}
			while(data>p.val) {
				if(p.right==null) {
					p.right=new TreeNode(data);
					return root;
				}
				p=p.right;
			}
		}
		return root;
		
	}
	//二叉树的查找
	public TreeNode findBST(TreeNode root,int data) {
		while(root!=null&&root.val!=data) {
			if(data<root.val) {
				root=root.left;
			}else {
				root=root.right;
			}
		}
		if(root!=null) {
			return root;
		}else {
			return null;
		}
		
	}
	//二叉树的删除(节点)
	public boolean removeBST(TreeNode root,int data) {
		return false;
	}

}
//测试类
public class test {
	public static void main(String[] args) {
		 int[] datas = new int[]{53, 17, 78, 9, 45, 65, 94, 23, 81, 88};
	     TreeNode root = null;
	     BST bst=new BST();
	     root=bst.creatBST(root, datas);
	     root=bst.findBST(root, 78);
	     System.out.println(root.right.val);
	}
}

4.字符串分割

str.substring(index1,index2);//左包右开

str.substring(index1);//index1到最后


5.树的层次遍历

层次遍历分为三种

类型解决方案
从左到右遍历(保存到一个结果中)

放入一个辅助队列中

还需要一个总输出链表

从左到右遍历(按行保存)

放入一个辅助队列中或者链表中

一个保存每行输出节点的链表,一个总输出链表

同时要有两个参数,一个记录每行节点数,一个计数,当两数相同时,加入总链表中,重置两个参数

奇数行从左到右,偶数行从右到左“之”字打印

两个辅助栈,其中A一个放从左到右的节点,另一个B放从右到左的节点

一个放每一行输出节点的链表,一个总输出链表

一个参数:

当参数为奇数时,放入B中,先放左再放右;

当参数为偶数时,放入B中,先放右再放左;

 

 //1
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
       ArrayList<Integer> ai=new ArrayList<>();
        if(root==null){
            return ai;
        }
        Queue<TreeNode>qi=new LinkedList<>();
        qi.offer(root);
        while(!qi.isEmpty()){
            TreeNode node=qi.poll();
            ai.add(node.val);
            if(node.left!=null){
                qi.offer(node.left);
            }
            if(node.right!=null){
                qi.offer(node.right);
            }
        }
        return ai;
 }

 

//2 
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer> >aai=new ArrayList<ArrayList<Integer> >();
        ArrayList<TreeNode> at=new ArrayList<TreeNode> ();
        if(pRoot==null){
            return aai;
        }
        at.add(pRoot);
        int index=0;
        int size=at.size();
        ArrayList<Integer> ai=new ArrayList<Integer>();
        while(!at.isEmpty()){
            TreeNode node=at.get(0);
            ai.add(node.val);
            at.remove(0);
            index++;
            if(node.left!=null)at.add(node.left);
            if(node.right!=null)at.add(node.right);
            if(index==size){
                aai.add(ai);
                index=0;
                size=at.size();
                ai=new ArrayList<>();
            }
        }
        return aai;
    }
//3
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer> > aai=new ArrayList<ArrayList<Integer> >();
        Stack<TreeNode> sr=new Stack<TreeNode>();
        Stack<TreeNode> sl=new Stack<TreeNode>();
        if(pRoot==null){
            return aai;
        }
        int index=1;
        sr.push(pRoot);
        while(!sr.isEmpty()||!sl.isEmpty()){
            ArrayList<Integer> ai=new ArrayList<Integer>();
            if(index%2==1){
                while(!sr.isEmpty()){
                    TreeNode node=sr.pop();
                    ai.add(node.val);
                    if(node.left!=null)sl.push(node.left);
                    if(node.right!=null)sl.push(node.right);
                }
                aai.add(ai);
                index++;
            }
             else{
                while(!sl.isEmpty()){
                    TreeNode node=sl.pop();
                    ai.add(node.val);
                    if(node.right!=null)sr.push(node.right);
                    if(node.left!=null)sr.push(node.left);
                }
                aai.add(ai);
                index++;
            }
        }
        return aai;
    }


6.最大连续子数组(简单变形,还需要输出最大数组和的起始下标和结束下标)

需要一个max,一个sum,一个开始,一个结束,一个计数

public class JoinTest {
    public static void main(String [] args) throws InterruptedException {
    	int []array={-9,6,-3,-2,7,-15,1,2,2};
    	maxArray(array);
    	
}
    public static void maxArray(int []arrays) {
    	int max=Integer.MIN_VALUE;
    	int start=0,end=0,index=0;//开始坐标,结束坐标,和计数坐标
    	int sum=0;
    	for(int i=0;i<arrays.length;i++) {
    		if(sum<=0) {
    			sum=arrays[i];
    			index=0;
    		}else {
    			sum+=arrays[i];
    			index++;
    			
    		}
    		if(sum>max) {
    			max=sum;
    			end=i;
    			start=end-index;
    		}
    	}
    	System.out.println(max);
    	System.out.println(start);
    	System.out.println(end);
    }
}   public class JoinTest {
    public static void main(String [] args) throws InterruptedException {
    	int []array={-9,6,-3,-2,7,-15,1,2,2};
    	maxArray(array);
    	
}
    public static void maxArray(int []arrays) {
    	int max=Integer.MIN_VALUE;
    	int start=0,end=0,index=0;//开始坐标,结束坐标,和计数坐标
    	int sum=0;
    	for(int i=0;i<arrays.length;i++) {
    		if(sum<=0) {
    			sum=arrays[i];
    			index=0;
    		}else {
    			sum+=arrays[i];
    			index++;
    			
    		}
    		if(sum>max) {
    			max=sum;
    			end=i;
    			start=end-index;
    		}
    	}
    	System.out.println(max);
    	System.out.println(start);
    	System.out.println(end);
    }
}   


7.手写一个双链表的插入和删除,查找方法

//链表
public class Link<T> {
	Link<T> pre=null;
	Link<T> next=null;
	T val;
	public Link(T val) {
		this.val=val;
	}
}
//双向链条
public class DoubleLink<T> {
	Link<T> first;
	Link<T> last;
	//判断为空
	public boolean isEmpty() {
		if(first==null) {
			return true;
		}else {
			return false;
		}
	}
	//插入头
	public void addFirst(T data) {
		Link<T> newlink=new Link<T>(data);
		if(isEmpty()==true) {
			last=newlink;//为空时,表尾指向新节点
		}else {	
			first.pre=newlink;//表头的前驱为新节点
		}
		newlink.next=first;//新节点的后继为表头
		first=newlink;//表头指向新节点
	}
	//插入尾
	public void addLast(T data) {
		Link<T> newlink=new Link<T>(data);
		if(isEmpty()==true) {
			first=newlink;//为空,表头指向新节点
		}else {	
			last.next=newlink;//表尾的后继为新节点
			newlink.pre=last;//新节点的前驱为表尾
		}
		last=newlink;//表尾执行新节点
	}
	//删除头
	public void removeFirst() {
		if(first.next==null) {//只剩一个或者没有
			last=null;
		}else {//不止一个节点
			first.next.pre=null;//表头后继的前驱为空
		}
		first=first.next;//表头指向下一个节点
	}
	//删除尾
	public void removeLast() {
		if(last.pre==null) {//只剩一个或者没有
			first=null;
		}else {//不止一个节点
			last.pre.next=null;//表尾前驱的后继为空
		}
		last=last.pre;//表尾指向前一个节点
	}
	//查找值==data的节点是否存在,
	public boolean isContain(T data) {
		if(first==null||last==null) {
			return false;
		}
		else {
			Link<T> newlink=first;
			if(first.val==data) {//头节点就是
				return true;
			}
			while(newlink.next.val!=data) {//不等
				newlink=newlink.next;
				
				if(newlink.next==null) {//遍历结束,未找到
					return false;
				}
			}
			return true;//存在
		}
	}
	//toString()方法
	public String toString() {
		if(isEmpty()) {
			return "";
		}else {
			StringBuffer sb=new StringBuffer("[");
			Link<T> newlink=first;
			while(newlink!=null) {
				if(newlink.next!=null) {
					sb.append(newlink.val+",");
				}else {
					sb.append(newlink.val);
				}
				newlink=newlink.next;
			}
			sb.append("]");
			return sb.toString();
		}
	}
}

结果显示:

false
[1,2,5]


8.k个排好序的数组,求一个最小区间,每个数组在这个区间里都至少有一个数

思路很简单:

定义两个参数

min:比较每个数组中最大的值,即数组最后一个值,取最小

max:比较每个数组中最小的值,即数组第一个值,取最大

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值