Leveraging Ranged Approach: Beats 80+ %
IntuitionOver specific ranges of part numbers, overhead is predictable. Use a piece-wise buildupApproachGiven that the suffix length is subtracted from the avai
# Intuition
Over specific ranges of part numbers, overhead is predictable. Use a piece-wise buildup

# Approach
Given that the suffix length is subtracted from the available space per part, and that suffix length is both dependent on the current part number's width in digit and dependent on width of the total part count, use a piece-wise subtraction.
Here, I have deduced that a single digit part number (1-9) will add 4 to the overhead for the suffix. The remaining overhead is taken by the number of total parts' digit count.
Rather than trying to calculate what's required, I instead throw ranges of digits at a test to see what will work. A range from 100 parts to 999 parts will use the same overhead per part. Likewise a range from 1 to 9 parts uses the same overhead as each other. So you do not have to know in advance that 687 parts are needed; you only need to guess that <= 999 parts are needed. The algorithm tells the exact number.
Note that this solution is not DRY. There is an opportunity to use another function or two to eliminate some redundant code.

# Complexity
- Time complexity:
O(N) - one thrip through the string message to build the outputs.

- Space complexity:
O(N) - output size is a duplicate of input size.

# Code
```java []
class Solution {

    public String[] splitMessage(String message, int limit) {
        if (limit < 5) {
            return new String[] {};
        }
        int mlen = message.length();
        int partsRequired = -1;
        int powerOfTen = 1;
        while (0 > (partsRequired = partsRequired(limit, powerOfTen, mlen))) {
            powerOfTen ++;
            if (powerOfTen > 5) {
                break;
            }
        }
        if (partsRequired == -1) {
            return new String[] {};
        }

        // Part Two: build all the parts.
        String[] rtnVal = new String[partsRequired];
        int sOffset = 0;
        int arrOffset = 0;
        String ending = "/" + partsRequired + ">";
        while (sOffset < mlen) {
            String suffix = "<" + (arrOffset+1) + ending;
            int endPt = Math.min(sOffset + (limit - suffix.length()), mlen);
            rtnVal[arrOffset] = message.substring(sOffset, endPt) + suffix;

            sOffset = endPt;            
            arrOffset ++;
        }
        return rtnVal;
    }

    /**
     * Settle the range based on powers of ten.
     * Assume 10,000, for example. This provides a wide range of values
     * that will all behave in the same way w.r.t. use of suffixes.
     */
    private int partsRequired(int limit, int powerOfTen, int msgSize) {
        int remainingChars = msgSize;
        int requiredParts = -1;
        if (powerOfTen == 1) {
            int perFragment = limit - overheadAtRegion(1, powerOfTen); // <n/n>
            if (perFragment < 0) {
                return -1;
            }       
            return checkRequired(remainingChars, perFragment, 9);
        }
        requiredParts = 9;
        // Reduce by how many we can get above.
        remainingChars -= availableAtRegion(limit, 1, powerOfTen) * 9;        

        if (powerOfTen == 2) {
            int perFragment = limit - overheadAtRegion(powerOfTen, powerOfTen); // <nn/nn>   
            if (perFragment < 0) {
                return -1;
            }      
            int atLevel = checkRequired(remainingChars, perFragment, 90);
            if (atLevel == -1) {
                return -1;
            }
            return requiredParts + atLevel;
        }
        requiredParts = 99;
        remainingChars -= availableAtRegion(limit, 2, powerOfTen) * 90;

        if (powerOfTen == 3) {
            int perFragment = limit - overheadAtRegion(powerOfTen, powerOfTen); // <nnn/nnn>
            if (perFragment < 0) {
                return -1;
            }
            int atLevel = checkRequired(remainingChars, perFragment, 900);     
            if (atLevel == -1) {
                return -1;
            }
            return requiredParts + atLevel;
        }
        requiredParts = 999;
        remainingChars -= availableAtRegion(limit, 3, powerOfTen) * 900;

        if (powerOfTen == 4) {
            int perFragment = limit - overheadAtRegion(powerOfTen, powerOfTen); // <nnnn/nnnn>
            if (perFragment < 0) {
                return -1;
            }
            int atLevel = checkRequired(remainingChars, perFragment, 9000);
            if (atLevel == -1) {
                return -1;
            }
            return requiredParts + atLevel;
        }        
        remainingChars -= availableAtRegion(limit, 4, powerOfTen) * 9000;

        // Not going above 10^5
        int perFragment = limit - overheadAtRegion(powerOfTen, powerOfTen); // <nnnnn/nnnnn>
        if (perFragment < 0) {
            return -1;
        }       
        int atLevel = checkRequired(remainingChars, perFragment, 90000);
        if (atLevel == -1) {
            return -1;
        }
        return requiredParts + atLevel;

    }

    private int checkRequired(int remainingChars, int perFragment, int maxAtLevel) {
        int requiredParts = (int)Math.ceil((double)remainingChars / (double)perFragment);
        if (requiredParts > maxAtLevel) {
            return -1;
        } else {
            return (int)requiredParts;
        }
    }

    private int availableAtRegion(int limit, int countSize, int powerOfTen) {
        return limit - overheadAtRegion(countSize, powerOfTen);
    }

    private int overheadAtRegion(int countSize, int powerOfTen) {
        return 3 + countSize + powerOfTen;
    }
}

```
['Java']