Leetcode--Array

1. Two Sum

用hash可以得到O(n)时间的解法,用python中的enumerate函数,可以获得元素的值及其坐标,通过dic[target - x] = i,将元素存入字典中,x最终一定会出现在dic里,然后返回当前的i,和dic[x],dic[x]就是回溯,去找之前第一次出现的x'
Time complexity: O(n)

4. Median of Two Sorted Arrays

  • 这道题可以扩展为寻找数列中的第k小元素,这里的k就是(len(nums1) + len(nums2))//2, 注意在python里://就是整除,只保留商的整数部分,如果想要获得小数结果,除数和被除数就至少应该有一个是float型,5/2.0 = 2.5, 5/2 = 2
  • 首先要判断两个数组的总长度是odd还是even,如果是odd,那就是找(l/2)小的元素,l是两个数组的总长度。如果是even,那就是找(第l/2小 + 第l/2-1小)/2
  • 寻找第k小元素:如果有一个数组不存在,就直接返回另一个数组的第k个元素。如果两个数组都存在,首先取各自长度的一半做下标,找到每个数组的median,然后判断两个下标的和与K的大小关系
  • 如果l1 + l2 < k,并且if m1 > m2:, 就去掉较小数组的前半段,并且更新k!!! k = k - l2/l1 -
    如果l1 + l2 > k, 就去掉较大数组的后半段。
    Time complexity: O(log(m+n))

15. 3Sum

固定一个元素,然后对剩下两个元素进行夹逼的方法。复杂度:O(n^2)

  • 注意要先对数组排序才行
  • for循环中的i只能取到len(nums)-2之前一个数。
  • for循环一开始先检测if i>0 and nums[i] == nums[i-1]: continue,这样可以避免出现重复结果
  • 当找到三个数相加为0时,也要避免出现重复结果,进行如下检验:
    while left < right and nums[left] == nums[left+1]: left += 1 while left < right and nums[right] == nums[right-1]: right -= 1

16. 3Sum Closest

跟第15题用的方法相似,也是固定一个元素然后进行夹逼。不同的是这道题要求找到与target最相近的元素和。所以我们应该初始化一个元素和,用它来做标准,通过之后的比较进行更新。
glo = nums[0] + nums[1] + nums[2]
因为这道题只有唯一解,所以不需要判断重复元素,每次直接更新Left和right就可以。

  • 需要注意的点就是,每次得出sum后,要和glo进行绝对值比较:
    if abs(sum - target) < abs(glo - target): glo = sum
  • while循环条件不要忘了while left < right

18. 4Sum

Time Complexity: O(n^2)
two sum + two sum = four sum

  • 维护一个value类型为List的hash table。将array里的元素两两相加,并将得到这个和的两个元素的下标作为value对存进去。因为两两相加的结果可能会有重复的,所以每个value的类型是list,会存很多个下标对
  • 两两相加结束后,就开始处理hash里的值。用dic.iteritems()这个迭代器取得key和value,key就是two sum,用target减去two sum,得到dif, 即另一个two sum。然后根据这个two sum,取得它对应的下标对,如果对应的下标对为空,就continue。若不为空,便对两个下标对组合进行遍历。
    for p1 in pair1:
    for p2 in pair2:
    i1, j1 = p1
    i2, j2 = p2
    if i1 in p2 or j1 in p2:
    continue
  • 这里的if判断非常重要,因为两个two sum的值可能完全相同,比如4等于2加2,所以他们取得的下标对就完全相同,这时为了避免出现由重复的下标对构成的结果,我们就要加入这个if判断

更新:

关于这里为什么一定要有if判断:是为了防止出现重复使用某个元素,比如p1:[(0,2), (0, 3)], p2:[(2,5), (3, 5)]
关于为什么res一定要用set,是为了去除重复结果,比如:
p1:[(0,2), (1, 5), (3, 5)], p2:[(0, 2), (1, 5), (3, 5)], 此时[nums[0], nums[2], nums[1], nums[5]]和[nums[0], nums[2], nums[3], nums[5]]都为结果, 但nums[1] == nums[3], 即两个结果完全一模一样,所以用set可以去除重复元素。

  • 对下表对对应的元素进行排序,将排序后的结果加入到res中。注意,res是set格式,这样可以去除重复元素,set添加元素用的是res.add()

454. 4Sum II

给四个数组,从每个数组中挑一个数字,看有多少个这样的组合相加为0。同样是拆成两个two sum来做

  • 用hash table存放前两个数组的two sum
  • 用hash table的get()函数找到0-后两个two sum的值,即前两个two sum的和。

dd.get()

dd.get(A[i] + B[j], 0)意思是如果字典里不存在A[i]+B[j],那就返回0
res += dd.get(0 - C[m] - D[k], 0)
0 - C[m] - D[k] 得到前一个two sum出现的次数,如果他存在,就加进 res, 如果不存在,就加0

  • 找到他们在hash里对应的值后,进行叠加,就是最终结果

26. Remove Duplicates from Sorted Array

Time Complexity: O(n)
从数组尾开始,判断是否nums[i] == nums[i-1],如果是,就删除掉nums[i-1],del nums[i-1]. 需要注意的是,不管是不是相等,都要i -= 1
不相等的情况比较好理解,相等时,因为删除掉一个元素,数组长度也少了一个,所以i也要减1,才能保持继续指向最后一个元素
如果从数组首端开始,当nums[i] == nums[i+1]时,只需要删除nums[i+1], 不需要移动i。while循环条件要注意:while i < len(nums)-1

27. Remove Element

Time Complexity: O(n)
题目虽然叫remove,但其实并不需要真的删除元素,只是把与target不同值的元素移到list最前边,并返回他们的size。好模糊的题目描述。
用了双指针方法,遇到和target一样的值了,就把左右指针元素交换位置,并将右指针向左移动。否则就将左指针向右移动。
最后返回left就可以
需要注意的是while循环条件中要包含等于:
while left <= right: 针对特殊情况:[1], val = 1

31. Next Permutation

要先理解next permutation是怎么得到的

  1. 从后往前找到两个相邻元素,保证后边的元素second大于前边的元素first
  2. 将从second开始到末尾的元素排序,即倒置
  3. 然后从first之后第一个元素开始查找比first大的元素,找到后将它和first交换位置即可
    reverse函数:
def reverse(self, nums, start, end):
        while start < end:
            nums[start], nums[end] = nums[end], nums[start]
            start = start + 1
            end = end - 1

33. Search in Rotated Sorted Array

用了Binary search,运行时间是O(logn)。因为数组在某个点被rotate了,所以可以看成是两个有序数组连在一起。按照binary search的方法先找到mid元素,然后将mid元素和left元素比较,就能发现从left到mid是否为有序,即:if nums[left] <= nums[mid]就为有序,然后可以判断target是否在这个有序序列中,如果在,我们就更新right = mid -1,不在:left = mid +1
如果是后半段有序,(对应上边if语句的else),就判断target是否在后边这个有序序列中,if nums[mid] <= target <= nums[right], 如果在,就更新left,反之更新right
这道题的思路就是比传统二分搜索多了一个判断sorted subarray的条件。

34. Search for a Range

题目要求运行时间控制在O(logn)形式,并且是有序数列,就可以想到要用binary search来做。

  • 需要注意的是,while left <= right: 要包含等号,因为有corner case like: [1], target = 1. 这时left = right
  • 和普通binary search不同的点就在于当nums[mid] == target时,要向mid的前后延伸,判断nums[mid]前后是否还有等于target的值。因为要返回一个索引范围,所以判断的同时要记录左右范围。

35. Search Insert Position

二分查找的实现,有三点需要注意

  • 当nums或者target为空时,返回空
  • while left <= right: 要有等号,因为列表里可能只有1个元素存在
  • return right + 1 因为while循环结束时,r一定在l左边,此时target不存在数组里,要返回可插入的索引,就是循环结束时r的右边第一个位置,所以是right+1

48. Rotate Image

将一个二维数组顺时针旋转九十度。

  • 先将二维数组进行reverse,然后进行两个for循环,外层循环对应行,内层循环对应列,内层循环范围是[i+1, n],因为reverse之后就对角线上的值就不用动了,每次只需要改变对角线之后的值

56. Merge Intervals

不要默认把interval当作数组类型,要看清题目的定义。
先对intervals以start进行排序,因为是多维列表排序,所以用到了lambda intervals.sort(key = lambda x: x.start)
然后先将第一个interval加入到res中res = [intervals[0]]
针对剩下的每个Interval:
for inter in intervals[1:] if inter.start > res[-1].end: res.append(inter) else: res[-1].end = max(res[-1].end, inter.end)
上一行代码中max的作用是针对:[1, 4], [2, 3]这种情况,即一个interval完全被另一个interval包含

73. Set Matrix Zeroes

follow up要求用constant space,思路是

  1. 维护两个变量row_0, col_0,分别用来标记第一行第一列的元素中是否有0存在。
  2. 做完标记后,从第二行第二列开始检查,如果有元素为0,就将与该元素对应的第一行,第一列的元素设为0.
  3. 检查第一行和第一列的元素,!! 注意是从第一行的第二个元素,和第一列的第二个元素开始检查。因为matrix[0][0]不对应任何内部元素!!!如果第一行有元素为0,就将这列的元素都设为0,如果第一列有元素为0,就将这一行的元素都设为0.
  4. 检查row_0和col_0,如果row_0为true, 就说明原始的矩阵,第一行有元素为0,所以应该将第一行元素设为0. 如果col_0为true,就应该将第一列元素设为0

75. Sort Colors

荷兰国旗问题:
http://www.cnblogs.com/gnuhpc/archive/2012/12/21/2828166.html

Paste_Image.png

图片来源:喜刷刷博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容