【歸併排序】求小和問題 [java/python]__python

來源:互聯網
上載者:User
問題描述

把數列中每個元素左邊小於自身的元素加起來

{1, 2, 3},2的左邊只有1小於,3左邊有1和2小於,加起來的小和值就是4

{1,3,5,0,2,4}1 3 5 | 0 2 41 3|5   0 2|41|3     0|2 

這個其實是練習歸併排序
已知歸併過程如下: 首先劃分劃分劃分,一直劃分到不能劃分,即每個組都只有一個數值。 然後合并,合并的過程就是每個二劃分排序的過程。 在合并的時候,開闢一個輔助數組,其大小等於這兩個合并數列的大小。 設定兩個指標分別指向每個數列的首部,然後比較得到其中較小的值,並將這個值放入輔助數組中。然後取出小值的那個數列的指標可以繼續向前走,與另一個數列的指標所指向的值繼續比較 這樣比較完成後,如果兩個數列中有個數列的數值有剩餘,即其指標沒有走到末尾,則將這個數列直接賦到輔助數組末尾即可。 然後將輔助數組中的值拷貝回原數組中剛才合并的那兩個數列的位置上。

其實就是在每次歸併排序的時候計算小於的和

count += a[p1] < a[p2] ? (r - p2 + 1)*a[p1] : 0;

java:

import java.io.*;class test  {   public static int smallSum(int[] arr) {        if (arr == null || arr.length < 2) {            return 0;        }        return mergeSort(arr, 0, arr.length - 1);    }    public static int mergeSort(int[] arr, int l, int r) {        if (l == r) {            return 0;        }        int mid = l + ((r - l) >> 1);        return mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r) + merge(arr, l, mid, r);    }    public static int merge(int[] arr, int l, int m, int r) {        int[] help = new int[r - l + 1];        int i = 0;        int p1 = l;        int p2 = m + 1;        int res = 0;        while (p1 <= m && p2 <= r) {            res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];        }        while (p1 <= m) {            help[i++] = arr[p1++];        }        while (p2 <= r) {            help[i++] = arr[p2++];        }        for (i = 0; i < help.length; i++) {            arr[l + i] = help[i];        }        return res;    }    public static void main (String[] args) throws java.lang.Exception    {        int[] arr = { 1,2,3};        System.out.println(smallSum(arr));    }}

python:

#!/usr/bin/python# -*- coding: utf-8 -*-def small_sum(arr):    if not arr or len(arr)<1:        return 0    return merge_sort(arr, 0, len(arr) - 1)def merge_sort(arr, l, r):    if l == r :        return 0    mid = l + ((r - l) >> 1)    return merge_sort(arr, l, mid) + merge_sort(arr, mid + 1, r) + merge(arr, l, mid, r)def merge(arr, l, m, r):    help = []    p1 = l    p2 = m + 1    res = 0    while p1 <= m and p2 <= r :        res += (r - p2 + 1) * arr[p1] if arr[p1] < arr[p2] else  0        if arr[p1] < arr[p2] :            help.append(arr[p1])            p1 += 1        else :            help.append(arr[p2])            p2 += 1    while p1 <= m :        help.append(arr[p1])        p1 += 1    while p2 <= r :        help.append(arr[p2])        p2 += 1    for i in range(len(help)):        arr[l + i] = help[i]    return res;from array import arrayarr = array('b', (1, 2, 3))print(small_sum(arr))

添加一個python版本是為了從之前的c/c++、java中的文法操作轉換過了,當然我對這代碼還是很不滿意的。之前學習了那麼久的python,以為自己掌握了文法,但真正轉換的時候還是挺碰壁的,有些不同的變化之前知道,但容易忘記還得查資料,python版本的代碼還想追求更pythonic,以後會不斷修改的。
希望各位博友能夠對python代碼提出更優雅格式的指點讓我學習,感謝。

來源資料:
牛客網左神演算法視頻:
https://www.nowcoder.com/
歸併過程來之該博友的總結:
https://blog.csdn.net/liuxiao214/article/details/78530993

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.