# Word Wrap problem ( Space optimized solution )

Given a sequence of words, and a limit on the number of characters that can be put in one line (line width). Put line breaks in the given sequence such that the lines are printed neatly. Assume that the length of each word is smaller than the line width. When line breaks are inserted there is a possibility that extra spaces are present in each line. The extra spaces includes spaces put at the end of every line except the last one.
The problem is to minimize the following total cost.
Total cost = Sum of cost of all lines, where cost of line is = (Number of extra spaces in the line)^2.
For example, consider the following string and line width M = 15
“Geeks for Geeks presents word wrap problem”
Following is the optimized arrangement of words in 3 lines
Geeks for Geeks
presents word
wrap problem
The total extra spaces in line 1 and line 2 are 0 and 2. Space for line 3 is not considered as it is not extra space as described above. So optimal value of total cost is 0 + 2*2 = 4.

Examples:

```Input format: Input will consists of array of integers where each array element represents length of each word of string. For example, for string S = "Geeks for Geeks", input array will be arr[] = {5, 3, 5}.
Output format: Output consists of a series of integers where two consecutive integers represent
starting word and ending word of each line.

Input : arr[] = {3, 2, 2, 5}
Output : 1 1 2 3 4 4
Line number 1: From word no. 1 to 1
Line number 2: From word no. 2 to 3
Line number 3: From word no. 4 to 4

Input : arr[] = {3, 2, 2}
Output : 1 1 2 2 3 3
Line number 1: From word no. 1 to 1
Line number 2: From word no. 2 to 2
Line number 3: From word no. 3 to 3 ```

Approach: We have discussed a Dynamic Programming based solution of word wrap problem. The solution discussed used O(n^2) auxiliary space. The auxiliary space used can be reduced to O(n). The idea is to use two 1-D arrays dp[] and ans[], where dp[i] represents minimum cost of the line in which arr[i] is the first word and ans[i] represents index of last word present in line in which word arr[i] is the first word. Let k represents limit on number of characters in each line. Suppose for any line l the first word in that line is at index i in arr[]. The minimum cost of that line is stored in dp[i]. The last word in that line is at index j in arr[], where j can vary from i to n. Iterate over all values of j and keep track of number of characters added so far in line l. If number of characters are less than k then find cost of current line with these number of characters. Compare this cost with minimum cost find so far for this line in dp[i] and update dp[i] and ans[i] accordingly. Repeat above procedure for each value of i, 1 <= i <= n. The starting and ending words of each line will be at index i and index ans[i], where next value of i for line l+1 is ans[i] + 1.

Implementation:

## C++

 `// C++ program for space optimized ` `// solution of Word Wrap problem. ` ` `  `#include ` `using` `namespace` `std; ` ` `  `// Function to find space optimized ` `// solution of Word Wrap problem. ` `void` `solveWordWrap(``int` `arr[], ``int` `n, ``int` `k) ` `{ ` `    ``int` `i, j; ` ` `  `    ``// Variable to store number of ` `    ``// characters in given line. ` `    ``int` `currlen; ` ` `  `    ``// Variable to store possible ` `    ``// minimum cost of line. ` `    ``int` `cost; ` ` `  `    ``// DP table in which dp[i] represents ` `    ``// cost of line starting with word ` `    ``// arr[i]. ` `    ``int` `dp[n]; ` ` `  `    ``// Array in which ans[i] store index ` `    ``// of last word in line starting with ` `    ``// word arr[i]. ` `    ``int` `ans[n]; ` ` `  `    ``// If only one word is present then ` `    ``// only one line is required. Cost ` `    ``// of last line is zero. Hence cost ` `    ``// of this line is zero. Ending point ` `    ``// is also n-1 as single word is ` `    ``// present. ` `    ``dp[n - 1] = 0; ` `    ``ans[n - 1] = n - 1; ` ` `  `    ``// Make each word first word of line ` `    ``// by iterating over each index in arr. ` `    ``for` `(i = n - 2; i >= 0; i--) { ` `        ``currlen = -1; ` `        ``dp[i] = INT_MAX; ` ` `  `        ``// Keep on adding words in current ` `        ``// line by iterating from starting ` `        ``// word upto last word in arr. ` `        ``for` `(j = i; j < n; j++) { ` ` `  `            ``// Update number of characters ` `            ``// in current line. arr[j] is ` `            ``// number of characters in ` `            ``// current word and 1 ` `            ``// represents space character ` `            ``// between two words. ` `            ``currlen += (arr[j] + 1); ` ` `  `            ``// If limit of characters ` `            ``// is violated then no more ` `            ``// words can be added to ` `            ``// current line. ` `            ``if` `(currlen > k) ` `                ``break``; ` ` `  `            ``// If current word that is ` `            ``// added to line is last ` `            ``// word of arr then current ` `            ``// line is last line. Cost of ` `            ``// last line is 0. Else cost ` `            ``// is square of extra spaces ` `            ``// plus cost of putting line ` `            ``// breaks in rest of words ` `            ``// from j+1 to n-1. ` `            ``if` `(j == n - 1) ` `                ``cost = 0; ` `            ``else` `                ``cost = (k - currlen) * (k - currlen) + dp[j + 1]; ` ` `  `            ``// Check if this arrangement gives ` `            ``// minimum cost for line starting ` `            ``// with word arr[i]. ` `            ``if` `(cost < dp[i]) { ` `                ``dp[i] = cost; ` `                ``ans[i] = j; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Print starting index and ending index ` `    ``// of words present in each line. ` `    ``i = 0; ` `    ``while` `(i < n) { ` `        ``cout << i + 1 << ``" "` `<< ans[i] + 1 << ``" "``; ` `        ``i = ans[i] + 1; ` `    ``} ` `} ` ` `  `// Driver function ` `int` `main() ` `{ ` `    ``int` `arr[] = { 3, 2, 2, 5 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr); ` `    ``int` `M = 6; ` `    ``solveWordWrap(arr, n, M); ` `    ``return` `0; ` `} `

## Java

 `// Java program for space  ` `// optimized solution of  ` `// Word Wrap problem. ` `import` `java.io.*; ` ` `  `class` `GFG ` `{ ` ` `  `// Function to find space  ` `// optimized solution of ` `// Word Wrap problem. ` `static` `void` `solveWordWrap(``int` `arr[], ` `                          ``int` `n, ``int` `k) ` `{ ` `    ``int` `i, j; ` ` `  `    ``// Variable to store  ` `    ``// number of characters  ` `    ``// in given line. ` `    ``int` `currlen; ` ` `  `    ``// Variable to store  ` `    ``// possible minimum  ` `    ``// cost of line. ` `    ``int` `cost; ` ` `  `    ``// DP table in which  ` `    ``// dp[i] represents  ` `    ``// cost of line starting ` `    ``// with word arr[i]. ` `    ``int` `dp[] = ``new` `int``[n]; ` ` `  `    ``// Array in which ans[i] ` `    ``// store index of last  ` `    ``// word in line starting  ` `    ``// with word arr[i]. ` `    ``int` `ans[] = ``new` `int``[n]; ` ` `  `    ``// If only one word is present  ` `    ``// then only one line is required.  ` `    ``// Cost of last line is zero.  ` `    ``// Hence cost of this line is zero.  ` `    ``// Ending point is also n-1 as  ` `    ``// single word is present. ` `    ``dp[n - ``1``] = ``0``; ` `    ``ans[n - ``1``] = n - ``1``; ` ` `  `    ``// Make each word first  ` `    ``// word of line by iterating  ` `    ``// over each index in arr. ` `    ``for` `(i = n - ``2``; i >= ``0``; i--)  ` `    ``{ ` `        ``currlen = -``1``; ` `        ``dp[i] = Integer.MAX_VALUE; ` ` `  `        ``// Keep on adding words in  ` `        ``// current line by iterating  ` `        ``// from starting word upto  ` `        ``// last word in arr. ` `        ``for` `(j = i; j < n; j++)  ` `        ``{ ` ` `  `            ``// Update number of characters ` `            ``// in current line. arr[j] is ` `            ``// number of characters in ` `            ``// current word and 1 ` `            ``// represents space character ` `            ``// between two words. ` `            ``currlen += (arr[j] + ``1``); ` ` `  `            ``// If limit of characters ` `            ``// is violated then no more ` `            ``// words can be added to ` `            ``// current line. ` `            ``if` `(currlen > k) ` `                ``break``; ` ` `  `            ``// If current word that is ` `            ``// added to line is last ` `            ``// word of arr then current ` `            ``// line is last line. Cost of ` `            ``// last line is 0. Else cost ` `            ``// is square of extra spaces ` `            ``// plus cost of putting line ` `            ``// breaks in rest of words ` `            ``// from j+1 to n-1. ` `            ``if` `(j == n - ``1``) ` `                ``cost = ``0``; ` `            ``else` `                ``cost = (k - currlen) *  ` `                       ``(k - currlen) + ` `                            ``dp[j + ``1``]; ` ` `  `            ``// Check if this arrangement ` `            ``// gives minimum cost for ` `            ``// line starting with word  ` `            ``// arr[i]. ` `            ``if` `(cost < dp[i])  ` `            ``{ ` `                ``dp[i] = cost; ` `                ``ans[i] = j; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Print starting index  ` `    ``// and ending index of  ` `    ``// words present in each line. ` `    ``i = ``0``; ` `    ``while` `(i < n)  ` `    ``{ ` `        ``System.out.print((i + ``1``) + ``" "` `+  ` `                        ``(ans[i] + ``1``) + ``" "``); ` `        ``i = ans[i] + ``1``; ` `    ``} ` `} ` ` `  `// Driver Code ` `public` `static` `void` `main (String[] args)  ` `{ ` `    ``int` `arr[] = {``3``, ``2``, ``2``, ``5``}; ` `    ``int` `n = arr.length; ` `    ``int` `M = ``6``; ` `    ``solveWordWrap(arr, n, M); ` `} ` `} ` ` `  `// This code is contributed ` `// by anuj_67. `

## Python 3

 `# Python 3 program for space optimized ` `# solution of Word Wrap problem. ` `import` `sys ` ` `  `# Function to find space optimized ` `# solution of Word Wrap problem. ` `def` `solveWordWrap(arr, n, k): ` ` `  `    ``dp ``=` `[``0``] ``*` `n ` ` `  `    ``# Array in which ans[i] store index ` `    ``# of last word in line starting with ` `    ``# word arr[i]. ` `    ``ans ``=` `[``0``] ``*` `n ` ` `  `    ``# If only one word is present then ` `    ``# only one line is required. Cost ` `    ``# of last line is zero. Hence cost ` `    ``# of this line is zero. Ending point ` `    ``# is also n-1 as single word is ` `    ``# present. ` `    ``dp[n ``-` `1``] ``=` `0` `    ``ans[n ``-` `1``] ``=` `n ``-` `1` ` `  `    ``# Make each word first word of line ` `    ``# by iterating over each index in arr. ` `    ``for` `i ``in` `range``(n ``-` `2``, ``-``1``, ``-``1``): ` `        ``currlen ``=` `-``1` `        ``dp[i] ``=` `sys.maxsize ` ` `  `        ``# Keep on adding words in current ` `        ``# line by iterating from starting ` `        ``# word upto last word in arr. ` `        ``for` `j ``in` `range``(i, n): ` ` `  `            ``# Update number of characters ` `            ``# in current line. arr[j] is ` `            ``# number of characters in ` `            ``# current word and 1 ` `            ``# represents space character ` `            ``# between two words. ` `            ``currlen ``+``=` `(arr[j] ``+` `1``) ` ` `  `            ``# If limit of characters ` `            ``# is violated then no more ` `            ``# words can be added to ` `            ``# current line. ` `            ``if` `(currlen > k): ` `                ``break` ` `  `            ``# If current word that is ` `            ``# added to line is last ` `            ``# word of arr then current ` `            ``# line is last line. Cost of ` `            ``# last line is 0. Else cost ` `            ``# is square of extra spaces ` `            ``# plus cost of putting line ` `            ``# breaks in rest of words ` `            ``# from j+1 to n-1. ` `            ``if` `(j ``=``=` `n ``-` `1``): ` `                ``cost ``=` `0` `            ``else``: ` `                ``cost ``=` `((k ``-` `currlen) ``*`  `                        ``(k ``-` `currlen) ``+` `dp[j ``+` `1``]) ` ` `  `            ``# Check if this arrangement gives ` `            ``# minimum cost for line starting ` `            ``# with word arr[i]. ` `            ``if` `(cost < dp[i]): ` `                ``dp[i] ``=` `cost ` `                ``ans[i] ``=` `j ` ` `  `    ``# Print starting index and ending index ` `    ``# of words present in each line. ` `    ``i ``=` `0` `    ``while` `(i < n): ` `        ``print``(i ``+` `1` `, ans[i] ``+` `1``, end ``=` `" "``) ` `        ``i ``=` `ans[i] ``+` `1` ` `  `# Driver Code ` `if` `__name__ ``=``=` `"__main__"``: ` `     `  `    ``arr ``=` `[``3``, ``2``, ``2``, ``5` `] ` `    ``n ``=` `len``(arr) ` `    ``M ``=` `6` `    ``solveWordWrap(arr, n, M) ` ` `  `# This code is contributed by ita_c `

## C#

 `// C# program for space  ` `// optimized solution of  ` `// Word Wrap problem.  ` `using` `System; ` ` `  `class` `GFG ` `{ ` ` `  `// Function to find space optimized  ` `// solution of Word Wrap problem.  ` `public` `static` `void` `solveWordWrap(``int``[] arr, ` `                                 ``int` `n, ``int` `k) ` `{ ` `    ``int` `i, j; ` ` `  `    ``// Variable to store number of  ` `    ``// characters in given line.  ` `    ``int` `currlen; ` ` `  `    ``// Variable to store possible  ` `    ``// minimum cost of line.  ` `    ``int` `cost; ` ` `  `    ``// DP table in which dp[i]  ` `    ``// represents cost of line  ` `    ``// starting with word arr[i].  ` `    ``int``[] dp = ``new` `int``[n]; ` ` `  `    ``// Array in which ans[i] store  ` `    ``// index of last word in line  ` `    ``// starting with word arr[i].  ` `    ``int``[] ans = ``new` `int``[n]; ` ` `  `    ``// If only one word is present  ` `    ``// then only one line is required.  ` `    ``// Cost of last line is zero.  ` `    ``// Hence cost of this line is zero.  ` `    ``// Ending point is also n-1 as  ` `    ``// single word is present.  ` `    ``dp[n - 1] = 0; ` `    ``ans[n - 1] = n - 1; ` ` `  `    ``// Make each word first  ` `    ``// word of line by iterating  ` `    ``// over each index in arr.  ` `    ``for` `(i = n - 2; i >= 0; i--) ` `    ``{ ` `        ``currlen = -1; ` `        ``dp[i] = ``int``.MaxValue; ` ` `  `        ``// Keep on adding words in  ` `        ``// current line by iterating  ` `        ``// from starting word upto  ` `        ``// last word in arr.  ` `        ``for` `(j = i; j < n; j++) ` `        ``{ ` ` `  `            ``// Update number of characters  ` `            ``// in current line. arr[j] is  ` `            ``// number of characters in  ` `            ``// current word and 1  ` `            ``// represents space character  ` `            ``// between two words.  ` `            ``currlen += (arr[j] + 1); ` ` `  `            ``// If limit of characters  ` `            ``// is violated then no more  ` `            ``// words can be added to  ` `            ``// current line.  ` `            ``if` `(currlen > k) ` `            ``{ ` `                ``break``; ` `            ``} ` ` `  `            ``// If current word that is  ` `            ``// added to line is last  ` `            ``// word of arr then current  ` `            ``// line is last line. Cost of  ` `            ``// last line is 0. Else cost  ` `            ``// is square of extra spaces  ` `            ``// plus cost of putting line  ` `            ``// breaks in rest of words  ` `            ``// from j+1 to n-1.  ` `            ``if` `(j == n - 1) ` `            ``{ ` `                ``cost = 0; ` `            ``} ` `            ``else` `            ``{ ` `                ``cost = (k - currlen) * ` `                       ``(k - currlen) + dp[j + 1]; ` `            ``} ` ` `  `            ``// Check if this arrangement  ` `            ``// gives minimum cost for  ` `            ``// line starting with word  ` `            ``// arr[i].  ` `            ``if` `(cost < dp[i]) ` `            ``{ ` `                ``dp[i] = cost; ` `                ``ans[i] = j; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Print starting index  ` `    ``// and ending index of  ` `    ``// words present in each line.  ` `    ``i = 0; ` `    ``while` `(i < n) ` `    ``{ ` `        ``Console.Write((i + 1) + ``" "` `+  ` `                      ``(ans[i] + 1) + ``" "``); ` `        ``i = ans[i] + 1; ` `    ``} ` `} ` ` `  `// Driver Code  ` `public` `static` `void` `Main(``string``[] args) ` `{ ` `    ``int``[] arr = ``new` `int``[] {3, 2, 2, 5}; ` `    ``int` `n = arr.Length; ` `    ``int` `M = 6; ` `    ``solveWordWrap(arr, n, M); ` `} ` `} ` ` `  `// This code is contributed  ` `// by Shrikant13 `

## PHP

 `= 0; ``\$i``--) ` `    ``{ ` `        ``\$currlen` `= -1; ` `        ``\$dp``[``\$i``] = PHP_INT_MAX; ` ` `  `        ``// Keep on adding words in current ` `        ``// line by iterating from starting ` `        ``// word upto last word in arr. ` `        ``for` `(``\$j` `= ``\$i``; ``\$j` `< ``\$n``; ``\$j``++)  ` `        ``{ ` ` `  `            ``// Update number of characters ` `            ``// in current line. arr[j] is ` `            ``// number of characters in ` `            ``// current word and 1 ` `            ``// represents space character ` `            ``// between two words. ` `            ``\$currlen` `+= (``\$arr``[``\$j``] + 1); ` ` `  `            ``// If limit of characters ` `            ``// is violated then no more ` `            ``// words can be added to ` `            ``// current line. ` `            ``if` `(``\$currlen` `> ``\$k``) ` `                ``break``; ` ` `  `            ``// If current word that is ` `            ``// added to line is last ` `            ``// word of arr then current ` `            ``// line is last line. Cost of ` `            ``// last line is 0. Else cost ` `            ``// is square of extra spaces ` `            ``// plus cost of putting line ` `            ``// breaks in rest of words ` `            ``// from j+1 to n-1. ` `            ``if` `(``\$j` `== ``\$n` `- 1) ` `                ``\$cost` `= 0; ` `            ``else` `                ``\$cost` `= (``\$k` `- ``\$currlen``) *  ` `                        ``(``\$k` `- ``\$currlen``) + ``\$dp``[``\$j` `+ 1]; ` ` `  `            ``// Check if this arrangement gives ` `            ``// minimum cost for line starting ` `            ``// with word arr[i]. ` `            ``if` `(``\$cost` `< ``\$dp``[``\$i``]) ` `            ``{ ` `                ``\$dp``[``\$i``] = ``\$cost``; ` `                ``\$ans``[``\$i``] = ``\$j``; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// Print starting index and ending index ` `    ``// of words present in each line. ` `    ``\$i` `= 0; ` `    ``while` `(``\$i` `< ``\$n``) ` `    ``{ ` `        ``echo` `(``\$i` `+ 1) . ``" "` `.  ` `             ``(``\$ans``[``\$i``] + 1) . ``" "``; ` `        ``\$i` `= ``\$ans``[``\$i``] + 1; ` `    ``} ` `} ` ` `  `// Driver function ` `\$arr` `= ``array``(3, 2, 2, 5); ` `\$n` `= sizeof(``\$arr``); ` `\$M` `= 6; ` `solveWordWrap(``\$arr``, ``\$n``, ``\$M``); ` ` `  `// This code is contributed  ` `// by Akanksha Rai ` `?> `

Output:

```1 1 2 3 4 4
```

Time Complexity: O(n^2)
Auxiliary Space: O(n)

My Personal Notes arrow_drop_up A Programmer and A Machine learning Enthusiast

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.