[LeetCode] Top Interview 150 Problems Solving # 228 Summary Ranges

Understanding the Problem

There is a sorted list of numbers. The numbers are either consecutive by 1 or non-consecutive. When the number are consecutive, they will be summarized like ”num1→num2” in a string format so It indicates from num1 to num2 the numbers are consecutive. For example, the inputs and outputs are expected as below

# input1
nums = [0, 1, 2, 4, 5, 7]
# output1
["0->2","4->5","7"]

# input2
nums = [0, 2, 3, 4, 6, 8, 9]
# output2
["0","2->4","6","8->9"]

Approach

Will it be good to be solved with two loops, one with while and another with for from the list? I had a deep thought for a while. I could have chosen two pointers but the fact that it will be somewhat closer to O(n²), I decided to solve the problem with only one for loop resulting in O(n).

I am pretty sure that my code will be more tidy if it comes with double loops, but I chose a single loop.

Solution

Before going into the loop, I had to make sure of these things

  1. I had to declare a list lists which will contain the string forms of the consecutive numbers, and will be the final return value.

  2. My code would look disheveled if I had written returning strings in every if clause, so I put aside the lambda functions summary and summary_last

  3. temp list will be used as a cache and values will be stacked before finally putting into lists.

Then I go with the loop eventually.

  1. in each sequence, the current number and the last number of temp will be compared whether to determine if the number is consecutive.

  2. If consecutive, the number will be stacked in the temp

  3. If not, the numbers in the temp will be listed in the lists, then the temp will be flushed leaving the current num so I will be compared with the next number

I thought this process will solve the solution, but I guess I was too naive. The final number was not considered at all. So I had to check if the number is the last number in each elif conditions.

class Solution:
    def summaryRanges(self, nums: List[int]) -> List[str]:
        lists = []
        if len(nums) == 0:
            return lists
        elif len(nums) == 1:
            return [f"{nums[0]}"]

        summary = lambda l : f"{l[-1]}" if len(l) == 1 else f"{l[0]}->{l[-1]}" # return form
        summary_last = lambda l, n : f"{n}" if len(l) == 1 else f"{l[0]}->{n}"

        temp = [nums[0]]
        for i, num in enumerate(nums):
            if i == 0:
                continue

            elif temp[-1] - num == -1: # when continuous
                temp.append(num)
                if i == len(nums)-1: # when last number
                    lists.append(summary_last(temp, num))

            elif temp[-1] - num != -1: # when no continuous
                lists.append(summary(temp))
                temp = [num]

                if i == len(nums)-1:# when last number
                    lists.append(summary_last(temp, num))

        return lists

Reflection

This was a challenging problem to me. I thought I was using too many if and elif clauses so I was having a hesitation to go further until the end. However, after solving the problem I had to ask chatGPT, then it gave me approximately a similar idea of solving the problem with many if clauses! The solution I came up with may not be the best but at least is a okay one.