剣指offerシリーズ-面接問題51.配列内の逆シーケンスペア(python)
17536 ワード
文書ディレクトリ 1. タイトル 2. 解題構想 2.1暴力法 2.3動的計画 2.3分治思想(集計並べ替え統計逆序数による) 3. コード実装 3.1暴力法 3.2動的計画 3.3分治思想(集計並べ替え統計逆序数による) 4. まとめ 5. 参考文献 1.テーマ
配列内の2つの数値で、前の1つの数値が後の数値より大きい場合、この2つの数値は逆シーケンスペアを構成します.配列を入力して、この配列の中の逆順序の対の総数を求めます
2.問題の解き方
詳細は暴力解法、分治思想、樹状配列を参照
2.1暴力法
これは何も言うことはない.
2.3動的計画
f(n)=f(n−1)+mであり、前の配列における現在の要素より大きい要素の個数.
2.3分治思想(集計ソートによる統計逆序数)
説明:このアルゴリズムを理解するには、「集計ソート」に詳しい必要があります.再帰関数を記述すると、毎回2つの分割配列のサブ区間に分割され、メソッドスタックがポップアップされると、2つの秩序配列が1つずつ結合され、最後にソート作業が完了することを把握します.
3.コード実装
3.1暴力法
O(n 2),空間複雑度S(n),タイムアウト.
3.2動的計画
O(n 2),空間複雑度S(n),タイムアウト.
3.3分治思想(集計並べ替えによる統計逆序数)
4.まとめ
この問題は私にはできません.
5.参考文献
[1]剣指offer叢書[2]剣指Offer-名企業面接官精講典型プログラミング問題[3]暴力解法、分治思想、樹状配列
配列内の2つの数値で、前の1つの数値が後の数値より大きい場合、この2つの数値は逆シーケンスペアを構成します.配列を入力して、この配列の中の逆順序の対の総数を求めます
2.問題の解き方
詳細は暴力解法、分治思想、樹状配列を参照
2.1暴力法
これは何も言うことはない.
2.3動的計画
f(n)=f(n−1)+mであり、前の配列における現在の要素より大きい要素の個数.
2.3分治思想(集計ソートによる統計逆序数)
説明:このアルゴリズムを理解するには、「集計ソート」に詳しい必要があります.再帰関数を記述すると、毎回2つの分割配列のサブ区間に分割され、メソッドスタックがポップアップされると、2つの秩序配列が1つずつ結合され、最後にソート作業が完了することを把握します.
3.コード実装
3.1暴力法
O(n 2),空間複雑度S(n),タイムアウト.
class Solution:
def reversePairs(self, nums: List[int]) -> int:
size = len(nums)
if size < 2:
return 0
res = 0
for i in range(0, size - 1):
for j in range(i + 1, size):
if nums[i] > nums[j]:
res += 1
return res
3.2動的計画
O(n 2),空間複雑度S(n),タイムアウト.
class Solution:
def reversePairs(self, nums: List[int]) -> int:
"""
1.
:
f(i) = f(i-1) + m;m nums[i]
"""
def count_large_number(arr, elem):
count = 0
for val in arr:
if val > elem:
count += 1
return count
if not nums: return 0
dp, i = [0 for i in nums], 1
while i < len(nums):
m = count_large_number(nums, nums[i])
dp[i] = dp[i-1] + m
i += 1
return dp[-1]
3.3分治思想(集計並べ替えによる統計逆序数)
class Solution:
def reversePairs(self, nums: List[int]) -> int:
size = len(nums)
if size < 2:
return 0
#
temp = [0 for _ in range(size)]
return self.count_reverse_pairs(nums, 0, size - 1, temp)
def count_reverse_pairs(self, nums, left, right, temp):
# nums [left, right]
if left == right:
return 0
mid = (left + right) >> 1
left_pairs = self.count_reverse_pairs(nums, left, mid, temp)
right_pairs = self.count_reverse_pairs(nums, mid + 1, right, temp)
reverse_pairs = left_pairs + right_pairs
# ,[left, mid] [mid + 1, right]
if nums[mid] <= nums[mid + 1]:
# , reverse_pairs
return reverse_pairs
reverse_cross_pairs = self.merge_and_count(nums, left, mid, right, temp)
return reverse_pairs + reverse_cross_pairs
def merge_and_count(self, nums, left, mid, right, temp):
"""
[left, mid] ,[mid + 1, right]
:[2, 3, 5, 8], :[4, 6, 7, 12]
, ,
" " " " ,
" " mid - i + 1 " "
"""
for i in range(left, right + 1):
temp[i] = nums[i]
i = left
j = mid + 1
res = 0
for k in range(left, right + 1):
if i > mid:
nums[k] = temp[j]
j += 1
elif j > right:
nums[k] = temp[i]
i += 1
elif temp[i] <= temp[j]:
# ,
nums[k] = temp[i]
i += 1
else:
# assert temp[i] > temp[j]
# , , ,
nums[k] = temp[j]
j += 1
# :[7, 8, 9][4, 6, 9],4 7 7
res += (mid - i + 1)
return res
:liweiwei1419
:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/solution/bao-li-jie-fa-fen-zhi-si-xiang-shu-zhuang-shu-zu-b/
: (LeetCode)
。 , 。
4.まとめ
この問題は私にはできません.
5.参考文献
[1]剣指offer叢書[2]剣指Offer-名企業面接官精講典型プログラミング問題[3]暴力解法、分治思想、樹状配列