กำหนด Array nums หาค่าเฉลี่ย (Mean) ของค่าที่เหลือหลังจากตัด 5% ต่ำสุด และ 5% สูงสุด ออก
ตัวอย่าง
- Input:
nums = [2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8](20 ตัว) - 5% ของ 20 = 1 ตัว ตัด 1 ตัวต่ำสุด (2) และ 1 ตัวสูงสุด (8)
- เหลือ 18 ตัวที่เป็น 4 ทั้งหมด → Mean = 4.0
โค้ด Python
def mean_after_removing_percentile(nums, percentile=5):
"""
หาค่าเฉลี่ยหลังตัด Percentile ต่ำสุดและสูงสุด
Args:
nums: List[float] - Input Array
percentile: int - Percentile to trim (default 5%)
Returns:
float - Trimmed Mean
"""
if not nums:
return 0.0
nums_sorted = sorted(nums)
n = len(nums_sorted)
# จำนวน Element ที่ตัดแต่ละข้าง (Floor)
k = int(n * percentile / 100)
# Slice ตัดทิ้ง k ตัวหน้าและ k ตัวท้าย
trimmed = nums_sorted[k : n - k]
if not trimmed:
return 0.0
return sum(trimmed) / len(trimmed)
# ทดสอบ
if __name__ == "__main__":
# Test Case 1: Example
nums = [2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8]
print(f"Input: {nums}")
print(f"Trimmed Mean (5%): {mean_after_removing_percentile(nums)}")
# Expected: 4.0
# Test Case 2: Normal distribution
import random
random.seed(42)
nums = [random.gauss(100, 15) for _ in range(1000)]
print(f"\nNormal Dist (n=1000): Mean={sum(nums)/len(nums):.2f}")
print(f"Trimmed Mean (5%): {mean_after_removing_percentile(nums):.2f}")
# Test Case 3: Outliers
nums = [1, 2, 3, 4, 5, 100, 200] # 7 elements, 5% = 0 (floor)
print(f"\nInput: {nums}")
print(f"Trimmed Mean (5%): {mean_after_removing_percentile(nums)}")
# k = 0, no trim, mean = 315/7 = 45
# Test Case 4: Exactly 20 elements
nums = list(range(1, 21)) # 1 to 20
print(f"\nInput: 1..20")
print(f"Trimmed Mean (5%): {mean_after_removing_percentile(nums)}")
# k = 1, trim 1 and 20, mean of 2..19 = 10.5
ผลลัพธ์
Input: [2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8] Trimmed Mean (5%): 4.0 Normal Dist (n=1000): Mean=99.87 Trimmed Mean (5%): 99.42 Input: [1, 2, 3, 4, 5, 100, 200] Trimmed Mean (5%): 45.0 Input: 1..20 Trimmed Mean (5%): 10.5
Complexity Analysis
- Time: O(n log n) เนื่องจาก Sorting
- Space: O(n) สำหรับ Sorted Copy
Statistically Robust: Trimmed Mean
วิธีนี้เรียกว่า Trimmed Mean (หรือ Truncated Mean) เป็น Robust Statistic ที่ทนทาน Outliers ดีกว่า Arithmetic Mean
ตัวแปรอื่นๆ ที่เกี่ยวข้อง
- Winsorized Mean: แทนที่ค่าต่ำสุด/สูงสุดด้วยค่าขอบเขต แทนที่จะตัดทิ้ง
- Median: 50% Trimmed Mean (ตัด 25% ทั้งสองข้าง)
- Interquartile Mean: ตัด 25% ทั้งสองข้าง (ใช้ IQR)
LeetCode Reference
Problem 1619: "Mean of Array After Removing Some Elements" - Easy