剑指编程(8)

一、
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
输入一个数组,求出这个数组中的逆序对的总数P。
并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
输入
1,2,3,4,5,6,7,0
输出
7

public class Solution {
    //用归并排序同时统计逆序对
    int res = 0;
    public int InversePairs(int [] array) {
        mergeSort(array, 0, array.length - 1);
        return res;
    }
    //归
    public void mergeSort(int[] array, int left, int right) {
        if(left < right) {
            int mid = (left + right) / 2;
            mergeSort(array, left, mid);
            mergeSort(array, mid + 1, right);
            merge(array, left, right);
        }
    }
    //并
    public void merge(int[] array, int left, int right) {
        int mid = (left + right) / 2;
        int i = left, j = mid + 1, k = 0;
        int[] tmp = new int[right - left + 1];
        while(i <= mid && j <= right) {
            if(array[i] <= array[j]) {
                tmp[k++] = array[i++];
            }else {
                tmp[k++] = array[j++];
                /* 两边数组都分别已排好序
                 * 如果L[i] > R[j],那么i~mid间的元素也将大于R[j]
                 * 左区间包含mid
                 */
                res += mid - i + 1;
                res %= 1000000007;
            }
        }
        while(i <= mid) {
            tmp[k++] = array[i++];
        }
        while(j <= right) {
            tmp[k++] = array[j++];
        }
        for(i = 0; i < tmp.length; i++) {
            array[left + i] = tmp[i];
        }
    }
}

二、
输入两个链表,找出它们的第一个公共结点。

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
public class Solution {
    //求长度,长度长的跳过长度差,然而两边逐个比对
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        int len1 = 0, len2 = 0;
        ListNode p1 = pHead1, p2 = pHead2;
        while(p1 != null) {
            p1 = p1.next;
            len1++;
        }
        while(p2 != null) {
            p2 = p2.next;
            len2++;
        }
        p1 = pHead1;
        p2 = pHead2;
        if(len1 > len2) {
            for(int i = 0; i < len1 - len2; i++) {
                p1 = p1.next;
            }
        }
        if(len2 > len1) {
            for(int i = 0; i < len2 - len1; i++) {
                p2 = p2.next;
            }
        }
        while(p1 != p2) {
            p1 = p1.next;
            p2 = p2.next;
        }
        return p1;
    }
}

三、
统计一个数字在排序数组中出现的次数。

public class Solution {
    //因为排序,只会出现在一段区间中
    public int GetNumberOfK(int [] array , int k) {
        int res = 0;
        //可以用二分法,即使不用也仅需O(n)复杂度
        for(int i = 0; i < array.length; i++) {
            if(array[i] == k) {
                while(i < array.length && array[i] == k) {
                    res++;
                    i++;
                }
                break;
            }
        }
        return res;
    }
}

四、
输入一棵二叉树,求该树的深度。
从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,
最长路径的长度为树的深度。

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;
        }
        return Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
    }
}

五、
输入一棵二叉树,判断该二叉树是否是平衡二叉树。

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    //左右子树高度绝对值小于等于1
    //子树同样是平衡二叉树
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) {
            return true;
        }
        if(Math.abs(TreeDepth(root.left) - TreeDepth(root.right)) > 1) {
            return false;
        }
        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }

    public int TreeDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        return Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值