সমস্যা বিবরণ
একটি অ্যারে arr দেওয়া আছে যেখানে প্রতিটি এলিমেন্ট খাদ্যের "স্বাদ-Saharan" (deliciousness) বোঝায়। দুটি ভিন্ন খাদ্যের সাম যদি ২-এর ঘাত (power of two: ১, ২, ৪, ৮, ১৬, ৩২...) হয়, তবে সেটাকে "Good Meal" বলা হয়। মোট কতটি уникаল "Good Meal" জোড়া সম্ভব তা বের করতে হবে।
উদাহরণ
- ইনপুট-১: arr = [1, 3, 5, 7, 9] → আউটপুট: ৪ (জোড়া: (1,3)=4, (1,7)=8, (3,5)=8, (7,9)=16)
- ইনপুট-২: arr = [1,1,1,3,3,3,7] → আউটপুট: ১৫ (জোড়া: (1,1) ৩টি, (1,3) ৯টি, (1,7) ৩টি)
সমাধানের পদ্ধতি (হ্যাশ ম্যাপ + পাওয়ার অফ টু চেক)
- অ্যারে সর্ট করুন (ঐচ্ছিক, কিন্তু লজিক সহজ করে)।
- হ্যাশ ম্যাপ (Dictionary) ব্যবহার করে প্রতিটি ভ্যালুর ফ্রিকোয়েন্সি ট্র্যাক করুন।
- প্রতিটি এলিমেন্ট
dএর জন্য সম্ভাব্য পাওয়ার অফ টুn(১, ২, ৪, ৮...2*dপর্যন্ত) চেক করুন। - প্রতিটি
nএর জন্য কমপ্লিমেন্টn - dহ্যাশ ম্যাপে আছে কিনা চেক করুন এবং কাউন্ট যোগ করুন। - মডুলো ১০⁹+৭ দিয়ে ফলাফল রিটার্ন করুন (লার্জ নাম্বার হ্যান্ডলিং)।
পূর্ণ কোড উদাহরণ (LeetCode স্টাইল)
from collections import defaultdict
from typing import List
class Solution:
def countPairs(self, arr: List[int]) -> int:
MOD = 10**9 + 7
arr.sort()
seen = defaultdict(int)
ans = 0
for d in arr:
n = 1
while n <= d + d: # সর্বোচ্চ সম্ভাব্য সাম ২*d
complement = n - d
if complement in seen:
ans = (ans + seen[complement]) % MOD
n <<= 1 # n = n * 2 (নেক্সট পাওয়ার অফ টু)
seen[d] += 1
return ans
# টেস্ট
sol = Solution()
print(sol.countPairs([1, 3, 5, 7, 9])) # ৪
print(sol.countPairs([1,1,1,3,3,3,7])) # ১৫
আউটপুট
4
15
ব্যাখ্যা
অ্যালগরিদমটি প্রতিটি এলিমেন্ট d প্রসেস করার সময় ইতিমধ্যে প্রসেস করা এলিমেন্টগুলো seen-এ রাখে। প্রতিটি পাওয়ার অফ টু n এর জন্য কমপ্লিমেন্ট n-d যদি seen-এ থাকে, তবে সতটিক জোড়া পাওয়া গেছে। সর্টিং নিশ্চিত করে ছোট মানগুলো আগে প্রসেস হয়।