剑指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);
        }
    }

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