Algorithm
本周选择的算法题是:Count of Smaller Numbers After Self
规则如下:
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i]
is the number of smaller elements to the right of nums[i]
.
Example 1:
Input: nums = [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
Constraints:
0 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
Solution
分析后发现从右往左遍历更容易得到答案,具体来说就是从右往左进行排序,这样一来问题就减化成了如何快速找到一个数字的位置,很自然就用了 right-most 的二分查找:
class Solution:
def countSmaller(self, nums: List[int]) -> List[int]:
arr, ans = [], [0] * len(nums)
def right_most(target: int):
left, right = 0, len(arr)
while left < right:
index = (left + right) // 2
if arr[index] >= target:
right = index
else:
left = index+1
return left
for i in range(len(nums)-1, -1, -1):
curr = nums[i]
inserted_index = right_most(curr)
if inserted_index == len(arr):
ans[i] = len(arr)
arr.append(curr)
else:
ans[i] = inserted_index
arr.insert(inserted_index, curr)
return ans
该方法的执行情况如下:
执行用时:132 ms, 在所有 Python3 提交中击败了95.11%的用户
内存消耗:15.6 MB, 在所有 Python3 提交中击败了97.73%的用户
同样是排序,评论区大佬有更好的策略:
class Solution:
def countSmaller(self, nums: List[int]) -> List[int]:
ans = [0] * len(nums)
def merger_sort(enums: List[int]):
half = len(enums) // 2
if half:
left, right = merger_sort(enums[:half]), merger_sort(enums[half:])
for index in range(len(enums)-1,-1,-1):
if not right or left and left[-1][1] > right[-1][1]:
ans[left[-1][0]] += len(right)
enums[index] = left.pop()
else:
enums[index] = right.pop()
return enums
merger_sort(list(enumerate(nums)))
return ans
归并排序思想,代码紧凑,非常好的思路!
Review
这是一家商业公司写的关于数据可视化的文章。
什么是数据可视化?
将数据进行采集、处理和模型化,然后把数据之间的复杂关系提炼成可视化的图形,以便得出结论。整个过程就是数据可视化。
它为什么重要?
主要是因为当今社会生产的数据太多了,目前整个世界每天生产2.5亿字节的数据,并且90%的数据是过去近两年时间生产的,这么多数据的管理、理解难度可想而知。
文章中的例子图如下:
- 传统的方式:
- 数据可视化之折线图:
后者更直观,如果表格中有成千上万条记录,虽然最终也能得出相同的结论,但是早,早就是优势,商业社会尤其如此,能帮助分析员、公司比竞争对手更快地做出决策就相当有价值。
更多内容见原文,有数据可视化发展的简史,各个图表的功能、受众等详细介绍。
Tip
为了解决安卓 CI 环境更新部署的问题,尝试将 sdk、ndk、环境变量以及其他依赖做了一份 docker 镜像,经过测试+观察后可以满足预期。
Share
Python 与 OC 内存管理的差异简要:
- 两者都是引用计数为主的策略,除此之外 Python 引入了 GC 来解决循环引用的问题
- Python 使用类似于标记-清除算法来处理循环引用:
- 标记 - 遍历所有对象,通过对计数-1来测试它们的可达性
- 清除 - 如果一个对象没有被标记为可达,则将其回收
- Python 为了优化 GC 效率,引入了分代回收
- Python 使用类似于标记-清除算法来处理循环引用:
- iOS 不支持 GC,不过早期的 OS X 系统是支持 GC 的:
- 10.5 通过 NSGarbageCollector 实现 GC,直到 10.8 被废弃
- 同 stop-the-world 不同,OC 的 GC 工作在一个低优先级的后台线程,并且它会在接收用户事件时中断,以快速响应用户的操作
- 关于 Python 的具体 GC 策略见这篇的 Review 部分