Как найти наименьшую подстроку, которая содержит все символы от данной строки?

Если вы просто установите margin-left: auto для четвертого элемента, вы должны получить желаемый результат.

.flex-list {
  list-style-type: none;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: space-between;
}

.flex-list li {
  font-family: Arial, sans-serif;
  font-size: 13px;
  padding: 15px 18px;
  border: 1px solid #069;
  color: #777;
  font-weight: bold;
}

.flex-list  .right {
  margin-left: auto;
}
<ul class="flex-list">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li class="right">4</li>
  <li>5</li>
</ul>

39
задан Rajendra Uppal 29 March 2019 в 15:04
поделиться

4 ответа

Вы можете выполнить развертку гистограммы за O(N+M) времени и O(1) пространства, где N - количество символов в первой строке, а M - количество символов во второй.

Это работает следующим образом:

  • Сделайте гистограмму символов второй строки (ключевая операция - hist2[ s2[i] ]++).
  • Составьте кумулятивную гистограмму символов первой строки до тех пор, пока в этой гистограмме не появятся все символы, которые есть в гистограмме второй строки (это я буду называть "условием гистограммы").
  • Затем продвигайтесь вперед по первой строке, вычитая из гистограммы, пока она не перестанет удовлетворять условию гистограммы. Пометьте эту часть первой строки (перед последним перемещением) как предварительную подстроку.
  • Снова переместите переднюю часть подстроки вперед, пока снова не будет выполнено условие гистограммы. Перемещайте конец вперед, пока он снова не выполнит условие гистограммы. Если эта подстрока короче первой, отметьте ее как предварительную подстроку.
  • Повторяйте, пока не пройдете всю первую строку.
  • Отмеченная подстрока - это ваш ответ.

Обратите внимание, что, изменяя проверку условия гистограммы, вы можете выбрать либо тот же набор символов, что и во второй строке, либо как минимум столько же символов каждого типа. (Это просто разница между a[i]>0 && b[i]>0 и a[i]>=b[i].)

Вы можете ускорить проверку гистограммы, если будете отслеживать, какое условие не выполняется, когда вы пытаетесь его выполнить, и проверять только то, которое вы декрементируете, когда пытаетесь его нарушить. (При начальном построении вы считаете, сколько элементов вы удовлетворили, и увеличиваете этот счет каждый раз, когда добавляете новый символ, переводящий условие из ложного в истинное)

.
33
ответ дан 27 November 2019 в 02:28
поделиться

Решение JavaScript способом "в лоб":

function shortestSubStringOfUniqueChars(s){
	var uniqueArr = [];
	for(let i=0; i<s.length; i++){
		if(uniqueArr.indexOf(s.charAt(i)) <0){
			uniqueArr.push(s.charAt(i));
		}
	}

	let windoww = uniqueArr.length;

	while(windoww < s.length){
		for(let i=0; i<s.length - windoww; i++){
			let match = true;
			let tempArr = [];
			for(let j=0; j<uniqueArr.length; j++){
				if(uniqueArr.indexOf(s.charAt(i+j))<0){
					match = false;
					break;
				}
			}
		let checkStr
		if(match){
			checkStr =  s.substr(i, windoww);
			for(let j=0; j<uniqueArr.length; j++){
				if(uniqueArr.indexOf(checkStr.charAt(j))<0){
					match = false;
					break;
				}
			}
		}
		if(match){
		    return checkStr;
		}
 	 }
 	 windoww = windoww + 1;
	}
}

console.log(shortestSubStringOfUniqueChars("ABA"));
0
ответ дан 27 November 2019 в 02:28
поделиться

Вот O(n) решение. Основная идея проста: для каждого начального индекса найти наименьший конечный индекс, такой, чтобы подстрока содержала все необходимые буквы. Хитрость в том, что наименьший конечный индекс увеличивается по ходу выполнения функции, поэтому с небольшой поддержкой структуры данных мы рассматриваем каждый символ не более двух раз.

В Python:

from collections import defaultdict

def smallest(s1, s2):
    assert s2 != ''
    d = defaultdict(int)
    nneg = [0]  # number of negative entries in d
    def incr(c):
        d[c] += 1
        if d[c] == 0:
            nneg[0] -= 1
    def decr(c):
        if d[c] == 0:
            nneg[0] += 1
        d[c] -= 1
    for c in s2:
        decr(c)
    minlen = len(s1) + 1
    j = 0
    for i in xrange(len(s1)):
        while nneg[0] > 0:
            if j >= len(s1):
                return minlen
            incr(s1[j])
            j += 1
        minlen = min(minlen, j - i)
        decr(s1[i])
    return minlen
6
ответ дан 27 November 2019 в 02:28
поделиться

Edit: по-видимому, существует алгоритм O(n) (см. ответ алгоритмиста). Очевидно, что это превзойдет [наивную] базовую линию, описанную ниже!

Жаль, что я должен пойти... Я немного подозреваю, что мы можем получить O(n). Я заеду завтра, чтобы увидеть победителя ;-) Веселитесь!

Предварительный алгоритм:
Общая идея состоит в том, чтобы последовательно попытаться использовать символ из str2, найденный в str1, в качестве начала поиска (в любом / обоих направлениях) всех других букв str2. Сохраняя значение «длина наилучшего соответствия до сих пор», мы можем прерывать поиск, когда они превышают это. Другие эвристики, вероятно, могут быть использованы для дальнейшего прерывания неоптимальных (пока) решений. Выбор порядка начальных букв в str1 имеет большое значение; предлагается начинать с буквы (букв) str1, которые имеют наименьшее количество, и пытаться с другими буквами, увеличивающимися, в последующих попытках.

  [loose pseudo-code]
  - get count for each letter/character in str1  (number of As, Bs etc.)
  - get count for each letter in str2
  - minLen = length(str1) + 1  (the +1 indicates you're not sure all chars of 
                                str2 are in str1)
  - Starting with the letter from string2 which is found the least in string1,
    look for other letters of Str2, in either direction of str1, until you've 
    found them all (or not, at which case response = impossible => done!). 
    set x = length(corresponding substring of str1).
 - if (x < minLen), 
         set minlen = x, 
         also memorize the start/len of the str1 substring.
 - continue trying with other letters of str1 (going the up the frequency
   list in str1), but abort search as soon as length(substring of strl) 
   reaches or exceed minLen.  
   We can find a few other heuristics that would allow aborting a 
   particular search, based on [pre-calculated ?] distance between a given
   letter in str1 and some (all?) of the letters in str2.
 - the overall search terminates when minLen = length(str2) or when 
   we've used all letters of str1 (which match one letter of str2)
   as a starting point for the search
0
ответ дан 27 November 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: