之前一直是拿LCR来练,最近把剑指offer的实体书买了。边看边练。
关于数组
数组相关的题目主要涉及到了两个概念。
把数组当作哈希表
数组的寻址是O(1)的,所以可以把数组当作哈希表来用。
然而,这时候的key也只能是int。
具体到这一题的优化: JZ3 数组中重复的数字
本来我的解法是再创建一个哈希表。 然而,考虑到数组中的元素只会存在于0~n-1之间,所以可以直接把数组当作哈希表来用。
它的核心便是尝试将对应的数字转移到对应的位置上。(例如,2应该在下标2的位置上)
如果该位置上已经存在了“正确的数”(也就是,已经存在了2),那么就说明这个数是重复的。
这个和用哈希的if num in num_set
的本质是一样的,但是我们只使用了O(1)的空间。
如果要求不改变原来的数组
使用广义的二分查找。
取取值的中点,随后计算小于等于中点的数的个数和大于中点的数的个数。 如果小于等于中点的数的个数大于中点,那么重复的数在左边;否则在右边。
字符串
事实上就讲述了一个从右到左的操作。
对于一个定长的数组(字符串也是数组的一种),如果从左到右复制(例如说,替换不同长度的字符串的时候), 会需要把后面的元素整块多次移动,复杂度会到O(n^2)。
这个时候,可以考虑从右到左复制。先扩张出足够的空间,然后准备一个读指针和一个写指针,从右到左复制。
具体请看: JZ5 替换空格