O(n) solution with O(1) space with "simple" math and problem constraints analysis
Intuition\nThe intuition is that no matter how many parts you have, they will always follow a pattern of digits. Any number between 100 and 999, for example, wi
# Intuition\nThe intuition is that no matter how many parts you have, they will always follow a pattern of digits. Any number between 100 and 999, for example, will always have 3 digits. So instead of combining everything and seeing if it magically works (I\'m looking at you brute-forcers), we can calculate how many parts we actually need by trying all possible max part **digits** combinations, which are constrained by the problem.\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n$$O(n)$$\n\n- Space complexity:\n$$O(1)$$, as the output does not count as space\n\n# Code\n```\nfrom typing import Optional, List, Tuple\nimport math\n\nclass Solution:\n\n    # O(n)\n    def splitMessage(self, message: str, limit: int) -> List[str]:\n        # Consider the smallest possible suffix: <1/1>\n        # It\'s already 5 digits. Can\'t work with that...\n        if limit <= 5:\n            return []\n        \n        # O(1)\n        def find_max_part() -> Optional[int]:\n            # Consider that at most we\'ll have 5 digits for the\n            # total part, as the problem is constrained to:\n            #\n            #   1 <= limit          <= 10**4\n            #   1 <= message.length <= 10**4\n            #\n            # In the worst case scenario, for the biggest message\n            # possible and the smallest (viable) limit, we can\n            # partition it in less than or equal to:\n            #\n            #     10 ** 4 = 10_000 parts  (which has 5 digits) [1]\n            #\n            # [1] This was revealed to me in a dream.\n            for total_digits in range(1, 5 + 1):\n                remaining = len(message)\n                parts = 0\n\n                # Start reducing the message. First we start by the\n                # 1 digit numbers, then 2 digit numbers, until we reach\n                # the current total_digits maximum.\n                for part_digits in range(1, total_digits + 1):\n                    # The maximum part can be calculated as such.\n                    #\n                    # This wields the following values:\n                    # [1,   9  ] => 10   - 1   = 9 items\n                    # [10,  99 ] => 100  - 10  = 90 items\n                    # [100, 999] => 1000 - 100 = 900 items\n                    max_part = 10 ** part_digits - 10 ** (part_digits - 1)\n\n                    suffix_len = 3 + part_digits + total_digits\n                    message_len = limit - suffix_len\n\n                    # No possible combination satisfies this. And \n                    # no possible >future< combination will neither, as\n                    # we\'re always increasing the number of digits.\n                    if message_len <= 0:\n                        return None\n\n                    # Calculate how many items we can fit here.\n                    # Be careful with the maximum this chunk can hold\n                    items_for_part = min(math.ceil(remaining / message_len), max_part)\n                    remaining -= items_for_part * message_len\n                    parts += items_for_part\n\n                    if remaining <= 0:\n                        return parts\n            \n            return None\n\n        max_part = find_max_part()\n        if not max_part:\n            return []\n\n        max_parts_str = str(max_part)\n        \n        i = 0\n        partitions = []\n        \n        # Simply build the partitions.\n        # O(n)\n        for part in range(1, max_part + 1):\n            part_str = str(part)\n            message_chunk_len = limit - (3 + len(part_str) + len(max_parts_str))\n            message_chunk = message[i:i+message_chunk_len]\n            i += message_chunk_len\n\n            partitions.append(f"{message_chunk}<{part_str}/{max_parts_str}>")\n        \n        return partitions\n\n```
['Python3']