LeetCode刷题之路(一)——easy的开始

来源:互联网 发布:广汽丰田一汽丰田 知乎 编辑:程序博客网 时间:2024/04/28 00:51

  从今天开始给自己立个flag,每天刷几个算法题,并将过程中遇到的问题或者碰到的一些比较巧妙的思路记录下来,供以后查阅,写在这里也算是对自己的监督。
  解题思路不限于比较难的题的解题思路,对于某些简单的题目比较巧妙的解法也进行说明。
  题目由易到难


Problem 1:Two sum

    Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not use the same element twice.

  题目很简单,给定一个数组和目标值,返回数组中两个数之和等于目标值的下标,并且总是有解的情况。

解题思路:
  1.直接对数组排序,然后分别从头(start)和从尾(end)向中间遍历,如果和大于目标值,end-1.如果和小于目标值,start+1,如果相等再去原数组找到相应的元素,这里有一个重复元素处理的问题。
  这是最笨的方法了,时间复杂度O(nlogn)(排序算法)
  2.用一个字典来维护,key等于tar减num[i]的差值,value为i,这样从头到尾遍历一次,如果当前的值在字典的key中,直接去当前位置和字典中该key对应的value。时间复杂度O(n)


Problem 7:Reverse Integer

  给定一个32位int,将其数字部分反转,也是123321,-123-321,如果结果越界,返回0

解题思路:
  题目很简单,注意下相关的检测就OK。
  python比较巧妙的一点就是可以用一句话实现正数的反转:

>>x = 123>>int(str(x)[::-1])>>321

Problem 9:Palindrome Integer

  判断一个数字是否是回文数字,不能使用额外的空间

解题思路:
  题目很简单,但是有几个坑:
    1. 输入是int,这里就默认了所有的负数都不是回文。
    2. 如果直接采用int反转,会有越界的可能。
  其实,我们只需要地反转原int 的后半部分,然后跟前半部分对比就可以了。


Problem 13: Roman to Integer

  将一个罗马数字转换成int,保证范围在0-3999

解题思路:罗马数字共有7个计数单位:

'M': 1000,'D': 500 ,'C': 100,'L': 50,'X': 10,'V': 5,'I': 1

  其中,XI = 11,IX=9,即,如果每个计数符号后面的比它小,我们就加,否则就减,从头到尾遍历字符串求解。


Problem 14:Longest Common Prefix

  输入一个字符串数组,找到它们的最长公共前缀。

解题思路:无非就是遍历,就看遍历中通过何种方法来检验是否满足条件能够简化复杂度。利用python的语言特性可以很简单的解决:

1.对于所有的字符串同时遍历,直到碰到第一个结尾:

for i,char_ in enumerate(zip(*strs)):

2.对每个遍历的位置,判断当前的字符集合是否有重复,也即所有的字符串在当前位置是否相等,如果不相等,那么自此位置之前的就是最长公共前缀,直接返回:

 if len(set(char_)) >1:                return strs[0][:i]

3.如果遍历结束,则最长前缀即最短的那个字符串:

 return min(strs)

Problem 20: Valid Parentheses

  给定一个字符串,包括’(‘, ‘)’, ‘{‘, ‘}’, ‘[’ 和 ‘]’的任意组合,判断该组合是否是一个合法的组合。

解题思路:使用栈,当为左括号时压入栈,当为右括号时从栈顶弹出并比较,如果匹配,则继续遍历,如果不匹配,则返回False。
  这里需要注意:因为左右括号的个数不一定相等,因此,弹出前要做是否为空的判断,为空直接返回False,同理,遍历完成后,栈为空才能返回True。
  这里涉及到python中的一个trick,因为python中没有栈和队列,因此全部用list实现:
  模仿队列时:入队l.append(),出队时调用l.pop(0)
  模仿栈时:入栈l.append(),出栈时调用l.pop()


Problem 21:Merge Two Sorted Lists

  给定两个排好序的链表,返回合并后的链表(仍为有序),要求使用原链表节点。

解题思路:总体思路即比较两个链表当前节点的值,去较小的连接到新链表的节点上,然后后移,当某一个链表遍历完毕,将另外一个链表的剩下部分接上去即可。
  生成新链表有两种方式,第一种将其看做独立的一个链表,每次只用改变这一个指针,第二种是取头结点值较小的为新链表的头结点,将该链表作为最终的链表,每次需要修改两个指针。

Problem 26: Remove Duplicates from Sorted Array

  给定一个排好序的数组,移除其中的重复元素,返回新数组的长度。
解题思路:从前向后遍历,设置两个指针,一个指针用来指向当前不重复的值,另一个向后遍历,如果遇到重复的,该指针就往后走,一旦出现不重复的,就将此后所有不重复的按顺序复制前一个指针的位置。如a=[1,2,2,2,3,3],t1=0,a[t1]=2,不重复,t1+=1,复制a[t1]=a[t2];a[t2]=2,重复,继续遍历,a[t2]=2,重复,继续;a[t2]=3,不重复,t1+=1,复制a[t1]=a[t2],此时数组为[1,2,3,2,3,3],继续遍历,重复,遍历结束,此时t1=2,即a[0]-a[t1]为[1,2,3]为不包括重复元素的数组。

Problem 27:Remove Element

  给定一个数组,移除其中值为val的元素,返回移除之后数组长度。解法同上

Problem 28:Implement strStr()

  给定一个字符串hastack,返回第一次出现needle串的索引,如果不存在返回-1
解题思路:直接遍历,进行子字符串相等判断,O(n)

Problem 35:Search Insert Position

  给定一个升序排列的整数数组和一个目标值,返回目标值在数列中的索引,如果不存在,返回目标值需要插入的位置从而保证插入后仍为有序
解题思路:遍历,当目标值存在时,返回索引位置,当目标值小于当前值时,代表不存在目标值,应该在当前位置插入目标值,也即:

if target <= nums[i]:    return i

如果遍历完毕,则在末尾插入,直接返回len(nums)


Problem 53:Maximum Subarray

  给定一个int数组,寻找和最大的子数组,并返回该最大值。譬如[-2,1,-3,4,-1,2,1,-5,4],最大和子数组为[4,-1,2,1],返回6。

解题思路:这题是个简单的动态规划题,不需要使用动态规划表,因为任何一个状态仅仅和前一个状态有关,我们考虑以i结尾的子串的最大和为temp_max,则它要么为以i-1结尾的最大值加上当前元素,要么就为当前元素,找到递推关系,然后求解即可。


Problem 58:Length of Last Word

  给定一个字符串,其中的单词用空格(个数不一定为1)隔开,返回最后一个单词的长度,如果不存在最后一个单词,则返回0。
解题思路:题目很简单,就是有几种情况需要考虑,第一即是多个空格隔开的情况,第二是形如”a “这种,第三是“ ”即空串,将这几种情况考虑进去就没问题了。可以先去除两端空格,然后用空格划分,判断最后一个元素的长度即可。


Problem 66:Plus One

  给定一个int数组,该数组所有元素合起来组成一个int,求加1后的结果,前面不能有0,譬如[9],则返回[1,0]。
解题思路:主要要考虑到最高位进1的情况,如果直接使用原数组会越界,因此我们可以在开始计算时在前面拼上一个0,计算结束通过判断该位置是否为0来决定返回值的形式。

原创粉丝点击