算法学习之剑指offer(七)

题目1

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5

示例1

输入

1,2,3,4,5,6,7,0

输出

7
public class Solution {
   int cnt=0;
 
    public int InversePairs(int[] array) {
        cnt = 0;
        if (array != null)
            mergeSortUp2Down(array, 0, array.length - 1);
        return cnt;
    }
	
    public void mergeSortUp2Down(int[] array,int start,int end){
        if(start>=end)
            return;
        
        int mid = (start+end)/2;
        mergeSortUp2Down(array,start,mid);
        mergeSortUp2Down(array,mid+1,end);
        
		sort(array,start,mid,end);
    }
    
    public void sort(int[] array,int start,int mid,int end){
        int p1=start,p2=mid+1,k=0;
        int tmp[] = new int[end-start+1];
       while(p1<=mid&&p2<=end){
           if(array[p1]>array[p2]){
               cnt+=mid-p1+1;
               cnt%=1000000007;
               tmp[k++]=array[p2++];
           }else{
               tmp[k++]=array[p1++];
           }
       }
       while(p1<=mid)
       		tmp[k++]=array[p1++];
        while(p2<=end)
       		tmp[k++]=array[p2++];
        
        for(int i=0;i<tmp.length;i++)
            array[start++]=tmp[i];
    }
}
题目2

题目描述

输入两个链表,找出它们的第一个公共结点。
一种自己的解法(如下,较长)+一种巧妙的解法(第二种,同时出发,走完不同路程的两个人 再走一遍对方走过的路 那么他们就会相遇)
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null)
            return null;
 		int length1=0,length2=0;
        ListNode node = pHead1;
        while(node!=null){
            length1++;
            node=node.next;
        }
        node = pHead2;
        while(node!=null){
            length2++;
            node=node.next;
        }
        ListNode firstGoNode;
        int chaValue=length2-length1;
        if(chaValue>0){
            firstGoNode=pHead2;node=pHead1;
        }else{
            firstGoNode=pHead1;node=pHead2;
        }
        if(chaValue<0)///之前少了这个地方!!!因为可能是负数!
            chaValue=-chaValue;
        while(chaValue>0){
            chaValue--;
            firstGoNode=firstGoNode.next;
        }
        while(node!=null&&firstGoNode!=null){
            if(node.val==firstGoNode.val)
                return node;
            firstGoNode=firstGoNode.next;
            node=node.next;
		}
        return null;
    }
}
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        while(p1!=p2){
            p1 = (p1==null ? pHead2 : p1.next);
            p2 = (p2==null ? pHead1 : p2.next);
        }
        return p1;
    }
}
题目3

题目描述

统计一个数字在排序数组中出现的次数。
public class Solution {
    public int GetNumberOfK(int [] array , int k) {
       int minIndex = getMinIndex(array,k);
       int maxIndex = getMaxIndex(array,k);
        
       return maxIndex-minIndex+1;
    }
    public int getMinIndex(int [] array , int k) {
       int start=0,end=array.length-1;
        int mid=(start+end)/2;
       while(start<=end){
           if(array[mid]<k){
               start=mid+1;
           }else{
               end=mid-1;
           }
           mid=(start+end)/2;
       }
       return start;
    }
    
    public int getMaxIndex(int [] array , int k) {
       int start=0,end=array.length-1;
        int mid=(start+end)/2;
       while(start<=end){
           if(array[mid]>k){
               end=mid-1;
           }else{
               start=mid+1;
           }
           mid=(start+end)/2;
       }
       return end;
    }
}
题目4

题目描述

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root==null)
            return 0;
        
        int left = TreeDepth(root.left);
        int right = TreeDepth(root.right);
        
        return left>right?left+1:right+1;
        
    }
}
题目5

题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。
public class Solution {
    
    boolean isBalanced = true;
    
    public boolean IsBalanced_Solution(TreeNode root) {
        getDepth(root);
        return isBalanced;
    }
    
    public int getDepth(TreeNode root) {
        if(root==null)
            return 0;
        int left = getDepth(root.left);
        int right = getDepth(root.right);
        if(Math.abs(left-right)>1)
        {
            isBalanced = false;
            return 0;//已经不是平衡二叉树没必要继续遍历了
        }
        return left>right?left+1:right+1;
    }
}
题目6

题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {

public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
       if(array==null ||array.length<2)
           return ;
       int temp = 0;
       for(int i=0;i<array.length;i++)
           temp ^= array[i];
        
       int indexOf1 = findFirstBitIs(temp);
       for(int i=0;i<array.length;i++){
           if(isBit(array[i], indexOf1))
               num1[0]^=array[i];
           else
               num2[0]^=array[i];
       }
   }
   public int findFirstBitIs(int num){
       int indexBit = 0;
       while(((num & 1)==0) && (indexBit)<8*4){
           num = num >> 1;
           ++indexBit;
       }
       return indexBit;
   }
   public boolean isBit(int num,int indexBit){
       num = num >> indexBit;
       return (num & 1) == 1;
   }

}








posted @ 2018-01-24 20:23  词汇族  阅读(161)  评论(0编辑  收藏  举报