Splitting a String Into Descending Consecutive Values

medium backtracking string

Problem

You are given a string s made up only of digits. Decide whether you can cut it into two or more contiguous pieces so that, reading left to right, the numeric value of each piece is exactly one less than the value of the piece before it. Leading zeros are allowed inside a piece (so "004" counts as the number 4). Return true if at least one such split exists, otherwise false.

Inputs = "050043"
Outputtrue
Split as "05", "004", "3" giving values 5, 4, 3 — each is one less than the previous.

def splitString(s):
    n = len(s)
    def backtrack(start, prev):
        if start == n:
            return True
        val = 0
        for end in range(start, n):
            val = val * 10 + int(s[end])
            if val == prev - 1 and backtrack(end + 1, val):
                return True
            if val >= prev:
                break
        return False
    first = 0
    for end in range(n - 1):
        first = first * 10 + int(s[end])
        if backtrack(end + 1, first):
            return True
    return False
function splitString(s) {
  const n = s.length;
  function backtrack(start, prev) {
    if (start === n) return true;
    let val = 0;
    for (let end = start; end < n; end++) {
      val = val * 10 + (s.charCodeAt(end) - 48);
      if (val === prev - 1 && backtrack(end + 1, val)) return true;
      if (val >= prev) break;
    }
    return false;
  }
  let first = 0;
  for (let end = 0; end < n - 1; end++) {
    first = first * 10 + (s.charCodeAt(end) - 48);
    if (backtrack(end + 1, first)) return true;
  }
  return false;
}
class Solution {
    public boolean splitString(String s) {
        int n = s.length();
        long first = 0;
        for (int end = 0; end < n - 1; end++) {
            first = first * 10 + (s.charAt(end) - '0');
            if (backtrack(s, end + 1, first)) return true;
        }
        return false;
    }
    private boolean backtrack(String s, int start, long prev) {
        if (start == s.length()) return true;
        long val = 0;
        for (int end = start; end < s.length(); end++) {
            val = val * 10 + (s.charAt(end) - '0');
            if (val == prev - 1 && backtrack(s, end + 1, val)) return true;
            if (val >= prev) break;
        }
        return false;
    }
}
bool backtrack(const string& s, int start, long long prev) {
    if (start == (int)s.size()) return true;
    long long val = 0;
    for (int end = start; end < (int)s.size(); end++) {
        val = val * 10 + (s[end] - '0');
        if (val == prev - 1 && backtrack(s, end + 1, val)) return true;
        if (val >= prev) break;
    }
    return false;
}
bool splitString(string s) {
    int n = s.size();
    long long first = 0;
    for (int end = 0; end < n - 1; end++) {
        first = first * 10 + (s[end] - '0');
        if (backtrack(s, end + 1, first)) return true;
    }
    return false;
}
Time: O(n2) per first-piece choice, O(n3) overall Space: O(n)