Блог пользователя LovesProgramming

Автор LovesProgramming, история, 7 лет назад, По-английски

You are given a string of length 'n'.

If a string contains at least one character whose frequency is greater than or equal to the half of the length of the string, then the string is called superior.

You are required to find the length of the longest superior substring available in the given string.

Note: Here half is considered under integer division i.e. 5/2=2 , etc.

The string contains only lowercase English alphabets.

I have tried O(n^2) solution(s) with some optimization(s) which obviously got timed out. I realized that there are better:- O(nlogn) or O(n) approaches,can anybody explain them?

Link to the problem statement :- https://www.hackerearth.com/practice/algorithms/searching/binary-search/practice-problems/algorithm/superior-substring-dec-circuits-e51b3c27/

Thanks :-)

  • Проголосовать: нравится
  • -6
  • Проголосовать: не нравится

»
7 лет назад, скрыть # |
 
Проголосовать: нравится -10 Проголосовать: не нравится

This should be solvable using a greedy solution using two pointer method. Take the largest substring from the left where there is a letter that makes it superior. As soon as this isn't true anymore, take another substring from the very next index and continue.

»
7 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +1 Проголосовать: не нравится

Deleted

»
7 лет назад, скрыть # |
Rev. 4  
Проголосовать: нравится 0 Проголосовать: не нравится

If half was defined as actual half then there is a nice way to solve it. Remember there was a blog about something close to this a while back but now I can't seem to find it. Will use python notation to explain my idea.

Let be defined as

sum(1 for c in S[:i] if c=='a')

which is the number of 'a' in the string at indices  < i. For a substring S[a:b], a < b, to contain half or more 'a's then

.

which is the same as

.

This inequality basically solves everything, just go through all indices sorted by while keeping track of the smallest index you've seen and you're basically done. Here is some pseudo-code:

a = n
longest_substring = 0
for b in sorted(range(n+1),key=lambda i:(2*A[i]-i,i)):
  if b-a>longest_substring:
    longest_substring = b-a
  a = min(a,b)

with this you can also do other fun stuff like calculating number of longest superior substrings and so on. The running time should be alphabet size times . It is possible to remove the using bucket sort, and it might also be possible to remove the scaling with the alphabet size by some modifications to the algorithm.

»
7 лет назад, скрыть # |
 
Проголосовать: нравится +26 Проголосовать: не нравится

Iterate over a letter that will be most frequent, and change the string into a sequence where every occurrence of the chosen letter is +1, and every other letter is -1. Then you're looking for the longest substring with a positive sum of values. This can be solved in O(n), so the whole problem is solvable in O(n·26).

  • »
    »
    7 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится

    Nice Idea, but a minor change is required This problem becomes a little different because of integer division definition. Lets say the string is: abc. Focusing on 'a' we get , 1 -1 -1 and the longest subarray with positive/0 sum is of length-2(0-1) but actually, the answer to this case is '3' cuz 3/2=1 which is the frequency of 'a' , so we have to find the longest subarray whose sum is >= -1 , thanks for the idea though :)