Python
December 15

Python. Задачи с собесов (draft)

В заметке приведено несколько задач с собесов, которые нужно было решать онлайн. Со временем возможно будут дополнения.

Задача: Написать функцию, которая считает сумму произведений всех элементов массива, исключая одно на каждом шаге. В массиве только положительные целые числа.

# multsum([1,5,6]) = 5*6 + 1*6 + 1*5 = 41

# multsum([1,5,6,7]) = 5*6*7 + 1*6*7 + 1*5*7+ 1*5*6 = 317

import math
def multsum(arr: list):
    total_product = math.prod(arr) # Вычисляем общее произведение всех чисел
    sum_of_excluded_products = 0
    
    for num in arr:
        sum_of_excluded_products += total_product // num
            
    return sum_of_excluded_products

Задача: Есть массив целых чисел и число K. Найти два таких (не обязательно различных) числа в массиве, сумма которых равна K, либо вывести, что таких чисел нет.

def find_two_sum(nums, K: int):
    """
    Находит два числа в массиве, сумма которых равна K.
    
    Args:
        nums: Список целых чисел.
        K: Целевая сумма.
        
    Returns:
        Кортеж из двух чисел, если пара найдена, или строка "null", если не найдена.
    """
    
    # Словарь для хранения чисел, которые мы уже встречали
    seen_numbers = {} 
    
    for num in nums:
        # Вычисляем число, которое дополнит текущее `num` до `K`
        complement = K - num
        
        # Если `complement` уже есть в нашем словаре `seen_numbers`,
        # значит, мы нашли нужную пару.
        if complement in seen_numbers:
            return (complement, num)
        
        # Если `complement` не найден, добавляем текущее `num` в словарь,
        # чтобы его могли найти на следующих шагах.
        # Значение в словаре (например, True или индекс) не имеет значения для этой конкретной задачи,
        # главное, чтобы ключ был добавлен.
        seen_numbers[num] = True 
        
    # Если цикл завершился, и мы не нашли пару, возвращаем "null"
    return "null"

Задача: Дана строка из латинских заглавных букв. Необходимо заменить все повторы одинаковых подряд идущих букв на букву + цифру. Одиночные буквы заменять не надо.

def compress_rle(s: str) -> str:
    """
    Сжимает строку: для подряд идущих одинаковых символов длины >= 2
    заменяет их на 'символ' + 'число'. Одиночные символы не меняет.
    Пример: "AAAABBB CAAA" -> "A4B3C A3" (пробелы сохраняются)
    """
    if not s:
        return ""
    
    res = []
    prev = s[0]
    count = 1
    
    for ch in s[1:]:
        if ch == prev:
            count += 1
        else:
            # Завершили блок
            if count == 1:
                res.append(prev)
            else:
                res.append(f"{prev}{count}")
            prev = ch
            count = 1
    
    # Добавляем последний блок
    if count == 1:
        res.append(prev)
    else:
        res.append(f"{prev}{count}")
    
    return "".join(res)