1

I have come across the following problem statement:

You have a sentence written entirely in a single row. You would like to split it into several rows by replacing some of the spaces with "new row" indicators. Your goal is to minimize the width of the longest row in the resulting text ("new row" indicators do not count towards the width of a row). You may replace at most K spaces.

You will be given a sentence and a K. Split the sentence using the procedure described above and return the width of the longest row.

I am a little lost with where to start. To me, it seems I need to try to figure out every possible sentence length that satisfies the criteria of splitting the single sentence up into K lines.

I can see a couple of edge cases:

  1. There are <= K words in the sentence, therefore return the longest word.
  2. The sentence length is 0, return 0

If neither of those criteria are true, then we have to determine all possible combinations of splitting the sentence and the return the minimum of all those options. This is the part I don't know how to do (and is obviously the heart of the problem).

jcm
  • 5,499
  • 11
  • 49
  • 78
  • 3
    Did you look at http://stackoverflow.com/questions/2381525/algorithm-split-a-string-into-n-parts-using-whitespaces-so-all-parts-have-nearl ? It is a nearly identical question whose answers may help. – hatchet - done with SOverflow Oct 07 '15 at 03:29

3 Answers3

0

First Answer

What you want to achieve is Minimum Raggedness. If you just want the algorithm, it is here as a PDF. If the research paper's link goes bad, please search for the famous paper named Breaking Paragraphs into Lines by Knuth.

However if you want to get your hands over some implementations of the same, in the question Balanced word wrap (Minimum raggedness) in PHP on SO, people have actually given implementation not only in PHP but in C, C++ and bash as well.


Second Answer

Though this is not exactly a correct approach, it is quick and dirty if you are looking for something like that. This method will not return correct answer for every case. It is for those people for whom time to ship their product is more important.

Idea

  • You already know the length of your input string. Let's call it L;
  • When putting in K breaks, the best scenario would be to be able to break the string to parts of exactly L / (K + 1) size;
  • So break your string at that word which makes the resulting sentence part's length least far from L / (K + 1);
Community
  • 1
  • 1
displayName
  • 13,888
  • 8
  • 60
  • 75
  • Can't do that. If you have 2 breaks, you use the first one to split the sentance in 2 and the 2nd one doesn't matter because. If you would try to split it in 3 parts you would get smaller pieces (assumes a long sentence like "a a a a a a ..."). – Sorin Oct 07 '15 at 13:23
  • L / (K + 1): if you replace 2 spaces you get three segments. ?? – Ian Mercer Nov 23 '15 at 02:40
  • @IanMercer: Didn't get your point. If you want three breaks, it implies *K* = 3. Now you attempt to break the entire sentence of length *L* at that word which is least far from *L* / *K* ( = *L* / 3 ). – displayName Nov 23 '15 at 20:28
  • Question says " You may replace at most K spaces." Each space is replaced with a new row indicator. So if I replace one space, K=1 and there are two rows. etc. Right?? – Ian Mercer Nov 24 '15 at 02:01
  • @IanMercer: Thanks. Corrected it. Actually I modified this answer after a gap of more than a month, so ended up with that off by one mistake. – displayName Nov 24 '15 at 15:56
0

You can solve it by inverting the problem. Let's say I fix the length of the longest split to L. Can you compute the minimum number of breaks you need to satisfy it?

Yes, you just break before the first word that would go over L and count them up (O(N)).

So now that we have that we just have to find a minimum L that would require less or equal K breaks. You can do a binary search in the length of the input. Final complexity O(NlogN).

Sorin
  • 11,863
  • 22
  • 26
0

My recursive solution, which can be improved through memoization or dynamic programming.

 def split(self,sentence, K):
    if not sentence: return 0
    if ' ' not in sentence or K == 0: return len(sentence)
    spaces = [i for i, s in enumerate(sentence) if s == ' ']
    res = 100000
    for space in spaces:
        res = min(res, max(space, self.split(sentence[space+1:], K-1)))
    return res
Alan
  • 417
  • 1
  • 7
  • 22