算法題---拼多多

一般會問筆試中的題****

(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:比較每個數組中最小的值,即數組第一個值,取最大

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章