38. Count and Say

(Count and say in Laicode)

Given a sequence of number: 1, 11, 21, 1211, 111221, …

The rule of generating the number in the sequence is as follow:

1 is "one 1" so 11.

11 is "two 1s" so 21.

21 is "one 2 followed by one 1" so 1211.

Find the nth number in this sequence.

Assumptions:

  • n starts from 1, the first number is "1", the second number is "11"

Analysis

My idea is using dp to store each number from 1 to n. The other solution did not use that many space, which is better in space complexity.

My solution

public String countAndSay(int n) {
  if (n == 1) {
      return "1";
  }
  if (n == 2) {
      return "11";
  }
  String[] m = new String[n + 1];
  m[1] = "1"; m[2] = "11";
  for (int i = 3; i <= n; ++i) {
      char[] last = m[i - 1].toCharArray();
    StringBuilder sb = new StringBuilder();
    int j = 0;
    while (j < last.length) {
        int k = j + 1;
      while (k < last.length) {
          if (last[k] == last[j]) {
            k++;
        } else {
            break;
        }
      }
      if (k - j == 1) {
          sb.append(1); sb.append(last[j]);
      } else {
          sb.append(k - j); sb.append(last[j]);
      }
      j = k;
    }
    m[i] = sb.toString();
  }
  return m[n];
}

Better Solution:

public String countAndSay(int n) {
    String s = "1";
    while (n-- > 1) { 
        StringBuilder next = new StringBuilder(); 
        for (int i = 1, cnt = 1; i <= s.length(); i++, cnt++) {
            if (i == s.length() || s.charAt(i) != s.charAt(i - 1)) {
                next.append(cnt).append(s.charAt(i - 1));
                cnt = 0;
            }
        }
        s = next.toString();
    }
    return s;
}

results matching ""

    No results matching ""