算法day01

63 阅读1分钟

1.递归求最大值

public static int getMax(int[] arr, int left, int right) {
    if (left == right) {
        return arr[left];
    }
    int mid = left + (right - left) / 2;
    int leftMax = getMax(arr, left, mid);
    int rightMax = getMax(arr, mid + 1, right);
    return leftMax > rightMax ? leftMax : rightMax;
}

2.归并排序

public void mergeSort(int[] arr, int left, int right) {
    if (left == right) return;
    int mid = left + ((right - left) >> 1);
    mergeSort(arr, left, mid);
    mergeSort(arr, mid + 1, right);
    merge(left, mid, right,arr);
}

public void merge(int left, int mid, int right, int[] arr) {
    int[] help = new int[right - left + 1];
    int i = left;
    int j = mid + 1;
    int k = 0;
    while (i <= mid && j <= right) {
        if (arr[i] < arr[j]) {
            help[k++] = arr[i++];
        } else {
            help[k++] = arr[j++];
        }
    }
    while (i <= mid) {
        help[k++] = arr[i++];
    }
    while (j <= right) {
        help[k++] = arr[j++];
    }
    for (int i1 = 0; i1 < help.length; i1++) {
        arr[left + i1] = help[i1];
    }
}

归并排序扩展(小和问题): 数组中每个元素左侧小于该元素的值的和累加得到小和。 只需要在每次merge操作两个数组合并时将右侧数组中大于左侧数组指针指向元素的个数统计出来,乘当前元素的值,就算出了本次合并产生的小和,每次都是两个未统计过的数组合并所以不会产生重复统计。

public void merge(int left, int mid, int right, int[] arr) {
    int[] help = new int[right - left + 1];
    int i = left;
    int j = mid + 1;
    int k = 0;
    while (i <= mid && j <= right) {
        if (arr[i] < arr[j]) {
            res+=arr[i]*(right-j+1);
            help[k++] = arr[i++];
        } else {
            help[k++] = arr[j++];
        }
    }
    while (i <= mid) {
        help[k++] = arr[i++];
    }
    while (j <= right) {
        help[k++] = arr[j++];
    }
    for (int i1 = 0; i1 < help.length; i1++) {
        arr[left + i1] = help[i1];
    }
}