Сжатие строки

Средняя

Описание задачи #

Дана строка в виде массива символов. Необходимо написать функцию, которая сожмет входящий массив по следующему принципу:

Все изменения нужно совершить in-place, в качестве ответа функции вернуть количество символов в сжатой строке.


Ограничения #


Примеры #

  • Входные данные

    chars = ["a","a","b","b","c","c","c"]
    

    Ответ: 6

    Исходный массив должен быть преобразован в ["a","2","b","2","c","3"]

  • Входные данные

    chars = ["a"]
    

    Ответ: 1

  • Входные данные

    chars = chars = ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
    

    Ответ: 4

    Исходный массив должен быть преобразован в ["a","b","1","2"]

Решение #

Задача решается достаточно элементарно, главная загвоздка - замена элементов in-place.

Для решения нам потребуется несколько индексов:

Мы будем итерироваться по исходному массиву:

В конце нам останется «отрезать» хвост у исходного массива.

  • package main
    
    import "strconv"
    
    func compress(chars []byte) int {
    	newPositionIdx := 0
    
    	for firstElemIdx := 0; firstElemIdx < len(chars); firstElemIdx++ {
    		lastChar := chars[firstElemIdx]
    
    		lastElemIdx := firstElemIdx + 1
    		for lastElemIdx < len(chars) && chars[lastElemIdx] == lastChar {
    			lastElemIdx++
    		}
    
    		chars[newPositionIdx] = chars[lastElemIdx-1]
    		newPositionIdx++
    
    		if counter := lastElemIdx - firstElemIdx; counter > 1 {
    			for _, countChar := range strconv.Itoa(counter) {
    				chars[newPositionIdx] = byte(countChar)
    				newPositionIdx++
    			}
    
    		}
    
    		firstElemIdx = lastElemIdx - 1
    	}
    
    	chars = chars[:newPositionIdx]
    	return len(chars)
    }

  • export const compress = (chars: string[]): number => {
    	let newPositionIdx = 0;
    
    	for (let firstElemIdx = 0; firstElemIdx < chars.length; firstElemIdx++) {
    		const lastChar = chars[firstElemIdx];
    
    		let lastElemIdx = firstElemIdx + 1;
    		while (lastElemIdx < chars.length && chars[lastElemIdx] === lastChar) {
    			lastElemIdx++;
    		}
    
    		chars[newPositionIdx] = chars[lastElemIdx - 1];
    		newPositionIdx++;
    
    		const counter = lastElemIdx - firstElemIdx;
    		if (counter > 1) {
    			for (const countChar of counter.toString()) {
    				chars[newPositionIdx] = countChar;
    				newPositionIdx++;
    			}
    		}
    
    		firstElemIdx = lastElemIdx - 1;
    	}
    
    	chars.splice(newPositionIdx, chars.length - newPositionIdx);
    	return chars.length;
    }

Оценка сложности #

n - количество элементов в массиве.

По времени

Сложность по времени O(n), так как мы итерируемся по всем элементам массива.

По памяти

Сложность по памяти O(1), так как мы модифицируем массив in-place.

Оригинал задачи на Leetcode
< Предыдущая задача
Следующая задача >