Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

โปรแกรม Python เรียง Array ตามความถี่ของ Element (Frequency Sort)

เรียง Array ให้ Element ที่มีความถี่ (Frequency) น้อยกว่าอยู่หน้า ถ้าความถี่เท่ากัน เรียงตามค่าตัวเลขจากมากไปน้อย (Descending)

ตัวอย่าง

  • Input: nums = [1, 5, 3, 1, 3, 1, 2, 5]
  • Frequency: 1→3, 5→2, 3→2, 2→1
  • Output: [2, 5, 5, 3, 3, 1, 1, 1]
Sorted by Frequency Asc, then Value Desc:
Freq 1: [2]           → 2
Freq 2: [5, 3]        → 5, 5, 3, 3 (5 > 3)
Freq 3: [1]           → 1, 1, 1
Result: [2, 5, 5, 3, 3, 1, 1, 1]

โค้ด Python

from collections import Counter

def frequency_sort(nums):
    """
    เรียง Array ตามความถี่น้อยไปมาก ค่ามากไปน้อยเมื่อ Frequency เท่ากัน
    
    Args:
        nums: List[int]
    
    Returns:
        List[int] - Sorted Array
    """
    # นับความถี่
    freq = Counter(nums)
    
    # เรียง: Primary = Frequency (Asc), Secondary = Value (Desc)
    # Key: (freq[x], -x) เพราะ Python Sort เป็น Ascending
    return sorted(nums, key=lambda x: (freq[x], -x))


# ทดสอบ
if __name__ == "__main__":
    # Test Case 1
    nums = [1, 5, 3, 1, 3, 1, 2, 5]
    print(f"Input:  {nums}")
    print(f"Output: {frequency_sort(nums)}")
    # Expected: [2, 5, 5, 3, 3, 1, 1, 1]

    # Test Case 2: All same frequency
    nums = [4, 2, 3, 1]
    print(f"\nInput:  {nums}")
    print(f"Output: {frequency_sort(nums)}")
    # Expected: [4, 3, 2, 1] (All freq=1, sort by value desc)

    # Test Case 3: Negative numbers
    nums = [-1, 1, -1, 2, -1, 3]
    print(f"\nInput:  {nums}")
    print(f"Output: {frequency_sort(nums)}")
    # -1:3, 1:1, 2:1, 3:1 → [3, 2, 1, -1, -1, -1]

    # Test Case 4: Large numbers
    nums = [100, 100, 200, 200, 200, 300]
    print(f"\nInput:  {nums}")
    print(f"Output: {frequency_sort(nums)}")
    # 100:2, 200:3, 300:1 → [300, 100, 100, 200, 200, 200]

ผลลัพธ์

Input:  [1, 5, 3, 1, 3, 1, 2, 5]
Output: [2, 5, 5, 3, 3, 1, 1, 1]

Input:  [4, 2, 3, 1]
Output: [4, 3, 2, 1]

Input:  [-1, 1, -1, 2, -1, 3]
Output: [3, 2, 1, -1, -1, -1]

Input:  [100, 100, 200, 200, 200, 300]
Output: [300, 100, 100, 200, 200, 200]

วิธีอื่น: ใช้ Bucket Sort (O(n) Time)

def frequency_sort_bucket(nums):
    """ใช้ Bucket Sort - O(n) Time, O(n) Space"""
    if not nums:
        return []
    
    freq = Counter(nums)
    max_freq = max(freq.values())
    
    # Buckets: Index = Frequency, Value = List of Numbers
    buckets = [[] for _ in range(max_freq + 1)]
    for num, f in freq.items():
        buckets[f].append(num)
    
    # เรียงในแต่ละ Bucket: Value Descending
    for bucket in buckets:
        bucket.sort(reverse=True)
    
    # รวมผลลัพธ์: Frequency 1, 2, 3, ...
    result = []
    for f in range(1, max_freq + 1):
        for num in buckets[f]:
            result.extend([num] * f)
    
    return result


# ทดสอบ
print(frequency_sort_bucket([1, 5, 3, 1, 3, 1, 2, 5]))  # [2, 5, 5, 3, 3, 1, 1, 1]

Complexity Comparison

MethodTimeSpaceNote
sorted() + lambdaO(n log n)O(n)Simple, Pythonic
Bucket SortO(n)O(n)เร็วกว่าเมื่อ n ใหญ่, Max Freq ไม่ใหญ่เกินไป

LeetCode Reference

Problem 1636: "Sort Array by Increasing Frequency" - Easy