有一組不同高度的臺階,有一個整數陣列表示,陣列中每個數是臺階的高度,當開始下雨了(雨水足夠多)臺階之間的水坑會積水多少呢? 如下圖,可以表示為陣列[0,1,0,2,1,0,1,3,2,1,2,1],返
阿新 • • 發佈:2019-01-06
這是一道今日頭條的面試題
"""
有一組不同高度的臺階,有一個整數陣列表示,陣列中每個數是臺階的高度,當開始下雨了(雨水足夠多)臺階之間的水坑會積水多少呢?
如下圖,可以表示為陣列[0,1,0,2,1,0,1,3,2,1,2,1],返回積水量6。
"""
分析:(手繪,難看別嫌棄)
方法一:(兩次遍歷)
先在這個陣列中找到最大值,然後從左右兩邊遍歷。以左邊為例,只要當前的數字比下一個數字大,那麼這個數字的右邊就可以存水,按照這個思路去分析就可以了,右邊的也是一樣的道理。程式碼如下:
def water_volume(arr_list): """ 返回積水量 :param arr_list: 臺階陣列 :return: 返回積水量 """ arr_length = len(arr_list) # 陣列的長度 arr_max = 0 # 定義陣列的最大值 arr_max_pos = 0 # 定義陣列最大值的下標 for i in range(0, arr_length): if arr_max < arr_list[i]: arr_max = arr_list[i] arr_max_pos = i arr_max_left = 0 # 定義從最左邊開始遍歷的極大值 arr_max_right = 0 # 定義從最右邊開始遍歷的極大值 volumes = 0 # 定義容水量 for j in range(0, arr_max_pos): if arr_max_left < arr_list[j]: arr_max_left = arr_list[j] else: volumes += (arr_max_left - arr_list[j]) for k in range(arr_length - 1, arr_max_pos, -1): if arr_max_right < arr_list[k]: arr_max_right = arr_list[k] else: volumes += (arr_max_right - arr_list[k]) return volumes arr = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 6] res = water_volume(arr) print(res)
方法二:(一次遍歷)
整個的原理和方法一是一樣的,就是從左右兩邊同時遍歷,這樣只用一次就可以實現了。程式碼如下:
def water_volume(arr_list): """ 返回積水量 :param arr_list: 臺階陣列 :return: 返回積水量 """ arr_length = len(arr_list) # 陣列的長度 arr_left_pos = 0 # 從左開始遍歷的指標的下標 arr_right_pos = arr_length - 1 # 從右開始遍歷的指標的下標 arr_max_left = arr_list[arr_left_pos] # 從左開始遍歷的過程中的極大值 arr_max_right = arr_list[arr_right_pos] # 從右開始遍歷的過程中的極大值 volumes = 0 # 儲存容積的變數 while arr_left_pos < arr_right_pos: if arr_max_left < arr_max_right: arr_left_pos += 1 if arr_list[arr_left_pos] >= arr_max_left: arr_max_left = arr_list[arr_left_pos] else: volumes += (arr_max_left - arr_list[arr_left_pos]) else: arr_right_pos -= 1 # tmp_right = arr_list[arr_right_pos] if arr_list[arr_right_pos] >= arr_max_right: arr_max_right = arr_list[arr_right_pos] else: volumes += (arr_max_right - arr_list[arr_right_pos]) return volumes arr = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1] res = water_volume(arr) print(res)