Leetcode解题思路总结(Easy篇)
终于刷完了leetcode的前250道题的easy篇。好吧,其实也就60多道题,但是其中的套路还是值得被记录的。 至于全部code,请移步github,题目大部分采用python3,小部分使用C,如有问题和建议,欢迎指正。
String
有一个string库,可以返回各种string的汇总,很值得用。
当题目中需要实现字符串替代的时候,python中有一个自带的
translate()函数可以实现这个功能,具体可见Python3字符串替换replace(),translate(),re.sub()two pointers 在string题目中很常用,如前后pointers遍历整个string。
Two pointers
这个方法其实就是采用两个指针,分别指向string或者list或者linked list的不同位置进行遍历,其实在pythonic的解法中,这种pointer的实现方式就是数组的遍历。
eg1:141. Linked list Cycle
Given a linked list, determine if it has a cycle in it.
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head == None:
return False
runningman1 = head
runningman2 = head.next
while runningman2 != None and runningman2.next != None:
if runningman2 == runningman1 or runningman2.next == runningman1:
return True
runningman2 = runningman2.next.next
runningman1 = runningman1.next
return False
这个题目是一个关于linked list的题目,此解答用了两个运动员(two pointers)的方法,一个跑的慢,一个跑的快,如果有循环,则跑的快的人一定可以追上跑的慢的人。其实解题重要的还是逻辑思路,而实现方法真的是次要的。
其实这个题目还有一种方法也很棒,具体可移步到github
eg2: 167. Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.
这个题采用的是前后two pointers的方法进行夹击:
class Solution:
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
i,j = 0,len(numbers)-1
while(numbers[i]+numbers[j]!=target):
if numbers[i]+numbers[j] > target:
j -= 1
else:
i += 1
return i+1,j+1
eg3: 234. Palindrome Linked List
Given a singly linked list, determine if it is a palindrome.
Example: Input: 1->2->2->1 Output: true
1、这个问题可以拆解成两个问题: 一是找到该单链表的中间位置,二是反转链表
2、对于第一个问题(找到单链表的中间位置),可以通过two pointers 的方法进行,一个pointer每次走一步,另一个pointer每次走两步,当每次走两步的pointer到达final时,另一个pointer刚好在一半位置
3、对于第二个问题(反转单链表),可以标准性的分割成四个步骤:
nxt = slow.next slow.next = node node = slow slow = nxt
class Solution:
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
## find the mid
slow = fast = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
## reverse the second half
node = None
while slow:
nxt = slow.next
slow.next = node
node = slow
slow = nxt
## compare two halves
while node:
if node.val == head.val:
node = node.next
head = head.next
else:
return False
return True
bin运算
其实我以前一直不知道python也可以进行位运算,直到我发现了这个题目:
eg4: 136. Single Number
Given a non-empty array of integers, every element appears twice except for one. Find that single one.
我的做法很蠢,采用的是hashmap的做法,创建一个set,然后逐个适用in运算符进行比较。其实这道题用异或(xor)是最好的方式,因为两个相同的数进行异或的二进制计算会返回全零。
求和后相减也是一个好的方法。
def singleNumber1(self, nums):
return 2*sum(set(nums))-sum(nums)
def singleNumber2(self, nums):
return reduce(lambda x, y: x ^ y, nums)
def singleNumber3(self, nums):
return reduce(operator.xor, nums)
这里借用菜鸟教程里的一个图总结python里的位运算图:

eg5: 231. Power of Two
Given an integer, write a function to determine if it is a power of two.
这个题也一样,我采用的方法如下:如果一个数为2的幂,那么他的bin形式则只有一个1,
class Solution:
def isPowerOfTwo(self, n):
"""
:type n: int
:rtype: bool
"""
if n <= 0:
return False
return bin(n).count('1') == 1
还有一种更简单的方法,那就是判断n&(n-1) == 0。
note:&是位运算符。
Hash Table
其实对于python再说,hashtable直接用dict或者set就可以解决。
eg6: 205. Isomorphic Strings
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.
好的方法就是将s[i]和t[i]结对,然后再进行比较,使用set()即可:
def isIsomorphic(self, s, t):
return len(set(zip(s, t))) == len(set(s)) == len(set(t))
实际上,这道题我采用的是用两个dict,从头遍历s和t,若元素再dict中没有则add进dict,value值为此时s或t的index,若有则判断两个dict的当前元素是否是同一个value。
然而,其实用一个dict也可以搞定:
def isIsomorphic(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
found = {}
## 这个dict的key是s[i],value值是t[i]
for i in range(len(s)):
if s[i] in found:
if not found[s[i]] == t[i]:
return False
else:
if t[i] in found.values():
return False
found[s[i]] = t[i]
return True
另一种方法为使用find()函数。具体见github
eg7: 169. Majority Element
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array.
HashMap allows us to count element occurrences efficiently.
以下是我的原始方法:
class Solution:
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
countdict = {}
for num in nums:
if num not in countdict:
countdict[num] = 1
else:
countdict[num] += 1
return max(countdict.items(),key=lambda x:x[1])[0]
不过,原来有一个collections.Counter()可以自动计数的啊
class Solution:
def majorityElement(self, nums):
counts = collections.Counter(nums)
return max(counts.keys(), key=counts.get)
DP问题
在easy的题目中,最典型的就数买股票问题了。简单来说,动态规划问题就是每次问题的处理与上一次问题处理的结果有关
eg8: 121. Best Time to Buy and Sell Stock
Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit. Note that you cannot sell a stock before you buy one.
class Solution:
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if not prices:
return 0
else:
maxprofit = 0
minbuy = float('inf')
for p in prices:
maxprofit = max(maxprofit,p-minbuy)
minbuy = min(minbuy,p)
return maxprofit
eg9: 70. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
这也是个更典型的DP问题, 注意为了节省时间,为了不反复求解相同的子问题,可以采用1. 带备忘的自顶向下法 2. 自底向上法
下面为带备忘的方法:
class Solution:
def __init__(self):
self.demo = {}
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n in {1,2,3}:
return n
if n in self.demo:
return self.demo[n]
else:
value = self.climbStairs(n-1) + self.climbStairs(n-2)
self.demo[n] = value
return value
eg10: 198. House Robber
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
DP问题最重要的部分在于对于不同问题领域,最优子结构不同体现在两个方面:
1、原问题的最优解中涉及多少个子问题
2、在确定最优解使用哪些子问题时,我们需要考察多少中选择
所以,在coding之前,最好是画出问题的子问题图
对于这个例子来说,原问题需要涉及两个相邻的子问题,且只需比较demo[i]+num > demo[i+1]
class Solution:
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
demo = {}
demo[0] = nums[0]
demo[1] = max(nums[0:2])
for i, num in enumerate(nums[2:]):
if demo[i]+num > demo[i+1]:
value = demo[i]+num
else:
value = demo[i+1]
demo[i+2] = value
return demo[len(nums)-1]
Tree
Tree的操作我喜欢用recursion,将子结点看成新的子树进行递归。
eg11: 107. Binary Tree Level Order Traversal II
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
这个问题没有用递归,而是采用queue的方式进行解答,这个也很典型。
队列中保存处理的树
Leetcode解题思路总结(Easy篇)的更多相关文章
- LeetCode解题思路
刷完题后,看一下其他人的solution,受益匪浅. 可以按不同的topic刷题,比如数组.字符串.集合.链表等等.先做十道数组的题,接着再做十道链表的题. 刷题,最主要的是,学习思路. 多刷几遍.挑 ...
- Leetcode解题思想总结篇:双指针
Leetcode解题思想总结篇:双指针 1概念 双指针:快慢指针. 快指针在每一步走的步长要比慢指针一步走的步长要多.快指针通常的步速是慢指针的2倍. 在循环中的指针移动通常为: faster = f ...
- [LeetCode] 76. Minimum Window Substring 解题思路
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- [LeetCode] Minimum Size Subarray Sum 解题思路
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- [LeetCode] Word Break 解题思路
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...
- [LeetCode] Longest Valid Parentheses 解题思路
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- [LeetCode] 134. Gas Station 解题思路
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
- [LeetCode] 45. Jump Game II 解题思路
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法
Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...
随机推荐
- WebService技术简介
今天继续阅读<.Net 大局观>时看到一段关于WebService支持技术的论述,真是简明扼要: Web services的另一个重要应用是B2B整合,一般来说它也依赖Internet,将 ...
- Nodejs经验谈
前言 这里主要说一下之前使用Nodejs开发踩过的坑,只说坑不填坑,那就是赤裸地耍流氓,文中有大量的说明及填坑方法,了解的看官可以直接跳过. PS:说实话,Nodejs的坑确实蛮多的:但是上手简单,扩 ...
- PyQt IDE 环境搭建
Eric的安装 1.按照目前pyqt5的要求安装了python3的最新版 2 pip3 install PyQt5 3. pip3 install QScintilla 4.download eric ...
- jenkins构建基于gradle的springboot项目CI采坑(采用jar方式部署)
试了一堆插件,最后用的还是 publish over SSH jenkins基本配置不多说了,就是配置一下git仓储,配置一下gradle执行命令 clean bootRepackage 之后执行Se ...
- Java学习方向
又过了一段日子了,项目比之前要熟悉很多了,有很多要学的东西要提上日程了. 个人感觉java基础很重要,只有基础扎实了,才能更好的写出代码和提升自己,需要好好的学习,以下是大概需要学习的方向 # jav ...
- UML类图10分钟快速入门 - From 圣杰
虚线箭头指向依赖: 实线箭头指向关联: 虚线三角指向接口: 实线三角指向父类: 空心菱形能分离而独立存在,是聚合: 实心菱形精密关联不可分,是组合: 原文作者:圣杰 原文地址:http://www.j ...
- 3d轮播图(另一种方式,可以实现的功能更为强大也更为灵活,简单一句话,比酷狗优酷的炫)
前不久我做了一个3d仿酷狗的轮播图,用的技术原理就是简单的jquery遍历+css样式读写. 这次呢,我们换一种思路(呵呵其实换汤不换药),看到上次那个轮播吗?你有没有发现用jquery的animat ...
- ubuntu 命令整合2
通配符 * 匹配任意多个字符 ?匹配一个任意字符 示例:ls *.txt rm -rf *.txt 文本编辑器 vi.vim 格式:vi 文件名 编辑 vi的三种工作模式 正常模式(启动进入的模式) ...
- AbstractQueuedSynchronizer原理及代码分析
一.AQS简介 AbstractQueuedSynchronizer(AQS)是java.util.concurrent并发包下最基本的同步器,其它同步器实现,如ReentrantLock类,Reen ...
- Maven学习(八)-- 使用Nexus搭建Maven私服
摘自:http://www.cnblogs.com/xdp-gacl/p/4068967.html 一.搭建nexus私服的目的 为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人 ...