劍指offer(二)(來自牛客網)

1. 輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

public class Solution {
    public int NumberOf1(int n) {
        int t=0;
        char[] ch=Integer.toBinaryString(n).toCharArray();
        for(int i=0;i<ch.length;i++){
            if(ch[i]=='1'){
                t++;
            }
        }
        return t;
    }
}

解法二:

位操作

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

 2.快速冪

解法一:標準快速冪:

public class Solution {
    public double Power(double base,int exponent){
        if(base==0.0) return 0.0;
        if(exponent==0) return 1.0d;
        int e=exponent>0?exponent:-exponent;
        return exponent>0?absPower(base,e):1/absPower(base,e);
    }
    public double absPower(double base,int exponent){
        if(exponent%2==0){
            return Power(base*base,exponent/2);
        }
        else{
            return Power(base*base,exponent/2)*base;
        }
    }
}

解法二:位運算實現快速冪

public class Solution {
    public double Power(double base,int exponent){
        if(base==0.0) return 0.0;
        if(exponent==0) return 1.0d;
        int e=exponent>0?exponent:-exponent;
        return exponent>0?absPower(base,e):1/absPower(base,e);
    }
    public double absPower(double base,int exponent){
        if(exponent==0) return 1.0d;
        if((exponent&1)==1){
            exponent>>=1;
            return absPower(base*base,exponent)*base;
        }
        else{
            exponent>>=1;
            return absPower(base*base,exponent);
        }
    }
}

3.輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。

import java.util.ArrayList;
import java.util.List;
public class Solution {
    public void reOrderArray(int [] array) {
        ArrayList<Integer> list = new ArrayList<Integer>(array.length);
        int t=0;
        for(int i=0;i<array.length;i++){
            if((array[i]&1)==1){
                list.add(t++,array[i]);
            }
            else{
                list.add(list.size(),array[i]);
            }
        }
        for(int i=0;i<list.size();i++){
            array[i]=list.get(i);
        }
    }
}

4.找出鏈表的倒數第k個節點,真是坑的不行,只有五個點還能出現倒數第六個也是牛皮。

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        ListNode t = head;
        int len=0;
        while(head!=null){
            head=head.next;
            len++;
        }
        int l = len-k;
        if(l<0) return null;
        for(int i=0;i<l;i++){
            t=t.next;
        }
        return t;
    }
}

5.反轉鏈表:

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        ListNode temp=null,tempnext=null;
        while(head!=null){
            if(temp==null)
                temp = new ListNode(head.val);
            else temp=tempnext; 
            head=head.next;
            if(head==null) return temp;
            tempnext = new ListNode(head.val);
            tempnext.next=temp;
        }
        return temp;
    }
}

6.合併鏈表

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        ListNode last=null,temp=null;
        ListNode head;
        if(list1==null) return list2;
        if(list2==null) return list1;
        head = (list1.val<=list2.val)?(list1):(list2);
        while(list2!=null){
            while(list1!=null&&list2.val>=list1.val){
                last=list1;
                list1=list1.next;
            }
            temp=new ListNode(list2.val);
            last.next=temp;
            temp.next=list1;
            list2=list2.next;
            last=temp;
        }
        return head;
    }
}

有點噁心的是,再插入list2的節點後,last節點要繼續往前走一個。

7.判斷B二叉樹是否是A二叉樹的子結構:

import java.util.*;
public class Solution {
   public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root2==null) return false;
        if(root1==null) return false;
        //對兩棵樹進行先序遍歷
        LinkedList<Integer> list1 = new LinkedList<>();
        LinkedList<Integer> list2 = new LinkedList<>();
        preOrder(root1,list1);
        preOrder(root2,list2);
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        for(int i=0;i<list1.size();i++){
            sb1.append(list1.get(i));
        }
        for(int i=0;i<list2.size();i++){
            sb2.append(list2.get(i));
        }
        return sb1.indexOf(sb2.toString())>=0?true:false;
    }
    public void preOrder(TreeNode root,LinkedList list){
        if(root==null) return ;
        list.add(root.val);
        preOrder(root.left,list);
        preOrder(root.right,list);
    }
}

一開始沒想清楚,瘋狂遞歸,然後炸了,覺得這題怎麼這麼難,不應該啊。

後來想先層序遍歷拿到所有根節點,再對比根節點,然後突然想到,MD,先序遍歷比較就行了。

ps:list並沒有給出包含子序列的方法,contains和indexOf都是返回元素,不能返回序列。

所以只能轉成StringBuilder然後用indexOf了。

補充一個二叉樹的層序遍歷:

public class Solution{
    public static void levelOrder(TreeNode root){
        LinkedList<TreeNode> queue= new LinkedList<>();

        queue.add(root);
        while(!queue.isEmpty()){
            root=queue.pop();
            System.out.println(root.val);
            if(root.left!=null) queue.add(root.left);
            if(root.right!=null) queue.add(root.right);
        }
    }

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