Math problems on platforms like LeetCode often require a combination of mathematical insight, algorithmic thinking, and coding skills. These problems can range from simple arithmetic operations to complex mathematical theories. Here, I will explain some common types of math problems and the techniques used to solve them.
Common Types of Math Problems and Techniques
- Random Pick with Weight
 - Basic Calculator II
 - Pow(x, n)
 - K Closest Points to Origin
 - Continuous Subarray Sum
 - Random Pick Index
 - Maximum Swap
 - Add Strings
 
528. Random Pick with Weight
Problem: Given an array w of positive integers where w[i] describes the weight of index i, write a function pickIndex which randomly picks an index in proportion to its weight.
Approach:
- Use prefix sums and binary search.
 - Compute the prefix sum array and use binary search to pick an index based on a random number.
 
Code:
import random
import bisect
class Solution:
    def __init__(self, w):
        self.prefix_sums = []
        prefix_sum = 0
        for weight in w:
            prefix_sum += weight
            self.prefix_sums.append(prefix_sum)
        self.total_sum = prefix_sum
    def pickIndex(self):
        target = random.randint(1, self.total_sum)
        return bisect.bisect_left(self.prefix_sums, target)
# Example usage:
weights = [1, 3, 2]
obj = Solution(weights)
print(obj.pickIndex())  # Randomly returns 0, 1, or 2 based on weights
Explanation:
- Prefix Sums: Compute the prefix sum of weights.
 - Binary Search: Use binary search to find the index corresponding to a random target within the total weight range.
 
227. Basic Calculator II
Problem: Implement a basic calculator to evaluate a simple expression string containing non-negative integers, +, -, *, and / operators.
Approach:
- Use a stack to manage the numbers and operators.
 - Traverse the string and handle operations based on operator precedence.
 
Code:
def calculate(s):
    if not s:
        return 0
    stack = []
    num = 0
    sign = '+'
    s += '+'
    for c in s:
        if c.isdigit():
            num = num * 10 + int(c)
        elif c in '+-*/':
            if sign == '+':
                stack.append(num)
            elif sign == '-':
                stack.append(-num)
            elif sign == '*':
                stack.append(stack.pop() * num)
            elif sign == '/':
                stack.append(int(stack.pop() / num))
            sign = c
            num = 0
    return sum(stack)
# Example usage:
expression = "3+2*2"
print(calculate(expression))  # Output: 7
Explanation:
- Stack for Numbers: Use a stack to handle numbers and intermediate results.
 - Operator Precedence: Handle 
*and/immediately, defer+and-until the end. 
50. Pow(x, n)
Problem: Implement pow(x, n), which calculates x raised to the power n.
Approach:
- Use recursion and the concept of exponentiation by squaring.
 
Code:
def my_pow(x, n):
    def helper(x, n):
        if n == 0:
            return 1
        half = helper(x, n // 2)
        if n % 2 == 0:
            return half * half
        else:
            return half * half * x
    if n < 0:
        x = 1 / x
        n = -n
    return helper(x, n)
# Example usage:
x = 2.0
n = 10
print(my_pow(x, n))  # Output: 1024.0
Explanation:
- Recursion: Break down the problem into smaller subproblems using recursion.
 - Exponentiation by Squaring: Efficiently compute powers by squaring intermediate results.
 
973. K Closest Points to Origin
Problem: Given an array of points where points[i] = [xi, yi] represents a point on the XY plane, return the k closest points to the origin (0, 0).
Approach:
- Use a max-heap to keep track of the 
kclosest points. 
Code:
import heapq
def k_closest(points, k):
    max_heap = []
    for x, y in points:
        dist = -(x**2 + y**2)
        if len(max_heap) == k:
            heapq.heappushpop(max_heap, (dist, x, y))
        else:
            heapq.heappush(max_heap, (dist, x, y))
    return [(x, y) for (dist, x, y) in max_heap]
# Example usage:
points = [[1, 3], [-2, 2]]
k = 1
print(k_closest(points, k))  # Output: [[-2, 2]]
Explanation:
- Max-Heap: Use a max-heap to keep the closest 
kpoints by distance. - Distance Calculation: Calculate the Euclidean distance and maintain the closest points.
 
523. Continuous Subarray Sum
Problem: Given an integer array nums and an integer k, return true if nums has a continuous subarray of size at least two whose elements sum up to a multiple of k.
Approach:
- Use a hash map to store the running sum modulo 
k. 
Code:
def check_subarray_sum(nums, k):
    sum_map = {0: -1}
    running_sum = 0
    for i, num in enumerate(nums):
        running_sum += num
        if k != 0:
            running_sum %= k
        if running_sum in sum_map:
            if i - sum_map[running_sum] > 1:
                return True
        else:
            sum_map[running_sum] = i
    return False
# Example usage:
nums = [23, 2, 4, 6, 7]
k = 6
print(check_subarray_sum(nums, k))  # Output: True
Explanation:
- Running Sum: Calculate the running sum modulo 
k. - Hash Map: Use a hash map to track the first occurrence of each remainder and check the distance between occurrences.
 
398. Random Pick Index
Problem: Given an integer array nums with possible duplicates, implement the Solution class:
pick(target): Randomly returns the index of the target number.
Approach:
- Use reservoir sampling to handle random selection efficiently.
 
Code:
import random
class Solution:
    def __init__(self, nums):
        self.nums = nums
    def pick(self, target):
        count = 0
        result = -1
        for i, num in enumerate(self.nums):
            if num == target:
                count += 1
                if random.randint(1, count) == count:
                    result = i
        return result
# Example usage:
nums = [1, 2, 3, 3, 3]
target = 3
obj = Solution(nums)
print(obj.pick(target))  # Randomly returns one of the indices: 2, 3, or 4
Explanation:
- Reservoir Sampling: Ensure each index has an equal probability of being chosen.
 - Count Occurrences: Traverse the array, counting occurrences of the target and selecting based on random chance.
 
670. Maximum Swap
Problem: Given a non-negative integer, you can swap two digits at most once to get the maximum valued number. Return the maximum valued number.
Approach:
- Use a greedy algorithm to find the best swap.
 
Code:
def maximum_swap(num):
    digits = list(str(num))
    last = {int(x): i for i, x in enumerate(digits)}
    for i, x in enumerate(digits):
        for d in range(9, int(x), -1):
            if last.get(d, -1) > i:
                digits[i], digits[last[d]] = digits[last[d]], digits[i]
                return int(''.join(digits))
    return num
# Example usage:
num = 2736
print(maximum_swap(num))  # Output: 7236
Explanation:
- Greedy Approach: Find the highest digit that can be swapped to maximize the number.
 - Track Last Occurrence: Use a dictionary to store the last occurrence of each digit for efficient swaps.
 
415. Add Strings
Problem: Given two non-negative integers represented as strings, return the sum of the two numbers as a string.
Approach:
- Use digit-by-digit addition with carry handling.
 
Code:
def add_strings(num1, num2):
    i, j = len(num1) - 1, len(num2) - 1
    carry = 0
    result = []
    while i >= 0 or j >= 0 or carry:
        x = int(num1[i]) if i >= 0 else 0
        y = int(num2[j]) if j >= 0 else 0
        total = x + y + carry
        carry = total // 10
        result.append(total % 10)
        i -= 1
        j -= 1
    return ''.join(map(str, result[::-1]))
# Example usage:
num1 = "123"
num2 = "456"'ML Engineering > python' 카테고리의 다른 글
| Heap/Quickselect | K Closest Points to Origin (0) | 2024.10.26 | 
|---|---|
| Heap/Quickselect| Finds the k-th smallest/largest element(s) in the list (0) | 2024.10.26 | 
| 07. Subset Techniques (0) | 2024.08.06 | 
| 06. Top K Elements Technique (0) | 2024.08.06 | 
| 05. Modified Binary Search Technique (0) | 2024.08.06 |