public static void textJustifiction(String[] words, int lineLength) {
        // this keeps the cost
        int[] justifyCost = new int[words.length+1];
        //this keeps the points from where we recived optimal or minimal cost
        int[] justifyPoints = new int[words.length+1];

        // base case  .. justify cost for empty string is 0
        justifyCost[words.length] = 0;

        int[] suffixLength = new int[words.length+1];

        // calculate suffix length
        for( int i = words.length-1; i >=0; i--) {
            suffixLength[i] = suffixLength[i+1]+ words[i].length();
        }

        // go backward from right to left
        for( int i = words.length-1; i >=0; i--) {
            // intially set the cost to be near infinite
            justifyCost[i] = Integer.MAX_VALUE - 900;
            // for every possible j starting from i+1 to n try calculating the cost.. pick the one with minimum cost
            for( int j = i+1; j <justifyCost.length; j++) {
                // length of the substring from (i-j) excluding word j
                int subStringlength = suffixLength[i] - suffixLength[j] ;

                // add one space per two words
                subStringlength += j -i -1;

                //calculate cost of substring(i to j)
                int cost  = 0;
                // if substring length is less than line length
                if(subStringlength <= lineLength) {
                    // cost will be equal to square of difference
                    cost = (lineLength - subStringlength) * (lineLength - subStringlength);
                } else {
                    // else cost will be infinite
                    cost = Integer.MAX_VALUE - 1000;
                }

                // now apply the main rule find minimum from justifyCost[j] + cost(i to j)
                if(justifyCost[j]+ cost < justifyCost[i]) {
                    justifyCost[i] = justifyCost[j] + cost;
                    // record the minimum point which yield to minimum value
                    justifyPoints[i] = j;
                }

            }
        }


        // Print the justified string
        int nextLine = justifyPoints[0];
        for( int i = 0; i<words.length; i++) {
            // if i becomes next line change the line while printing
            if( i == nextLine) {
                System.out.println();
                nextLine = justifyPoints[i];
            }
            // print the word
            System.out.print(words[i]);
            // determine when to print a single space
            if(i!=nextLine-1){
                System.out.print(" ");
            }
        }


    }