Zhuanli&Blog


  • 首页

  • 标签

  • 分类

  • 归档

leetcode 211. 添加与搜索单词 - 数据结构设计

发表于 2018-08-22 | 分类于 leetcode

设计一个支持以下两种操作的数据结构:

void addWord(word)
bool search(word)

search(word) 可以搜索文字或正则表达式字符串,字符串只包含字母 . 或 a-z 。 . 可以表示任何一个字母。

示例:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

说明:

你可以假设所有单词都是由小写字母 a-z 组成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class WordDictionary:
def __init__(self):
self.root = {}

def addWord(self, word):
k = len(word)
if k in self.root.keys():
self.root.get(k).add(word)
else:
self.root.setdefault(k, set([word]))

def search(self, word):
k = len(word)
if k in self.root.keys():
ls = list(self.root.get(k))

if word in ls:
return True
for i, w in enumerate(word):
if w == '.':
continue
ls = [words for words in ls if words[i] == w]
if not ls:
return False
return True

else:
return False

leetcode 210. 课程表 II

发表于 2018-08-22 | 分类于 leetcode

现在你总共有 n 门课需要选,记为 0 到 n-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。

可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

示例 1:

输入: 2, [[1,0]] 
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

输入: 4, [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
     因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3] 。

说明:

  • 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
  • 你可以假定输入的先决条件中没有重复的边。

提示:

  • 这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。
  • 通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。
    拓扑排序也可以通过 BFS 完成。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import collections
class Solution:
def findOrder(self, numCourses, prerequisites):
self.graph = collections.defaultdict(list)
self.res = []
for pair in prerequisites:
self.graph[pair[0]].append(pair[1])
self.visited = [0 for x in range(numCourses)]
for x in range(numCourses):
if not self.dfs(x):
return []
return self.res

def dfs(self, node):
if self.visited[node] == -1:
return False
if self.visited[node] == 1:
return True
self.visited[node] = -1
for x in self.graph[node]:
if not self.dfs(x):
return False
self.visited[node] = 1 # mark as finished
self.res.append(node)
return True

回溯算法解决数独问题

发表于 2018-08-22 | 分类于 python

数独规则:
1-9的数不能出现在同一列,同一行,或者同一个3*3的格子中。

算法思想如下:

  • 1 )找到一个空格子,如果找不到, 说明已经填满,这是一个解,返回true
  • 2 )从1 - 9 的数字中填上找到的空格子,如果合法
    • 2.1 生成部分解,递归调用 1)2) 3)
    • 2.2 如果递归调用返回true,说明合法
    • 2.3 回溯部分解
  • 3)上述都不成,直接返回false

解法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import sys
sys.setrecursionlimit(10000)
def solveSudo(board):
helper(board)

def helper(board):
#step1, 获取一个空格, 如果没找到,说明已经填满。
row,col = getUnsignedOne(board)
if row == -1:
return True
#Step2: 从1-9 分别填上棋盘
for num in range(1,10):
if isValid(board,row,col,num):
#step2.1 生成部分解,递归调用
board[row][col] = num
#step2.2
if helper(board):
return True
#Step2.3 回溯
board[row][col] = 0
return False

def getUnsignedOne(board):
for i in range(9):
for j in range(9):
if board[i][j] == 0:
return i,j
return -1,-1

def isValid(board,row,col,num):
for i in range(9):
if board[i][col] == num:
return False

for i in range(9):
if board[row][i] == num:
return False

startRow = row - row%3
startCol = col - col%3
for i in range(3):
for j in range(3):
if board[startRow+i][startCol+j] == num:
return False
return True

board = [[8,0,0,5,6,4,2,0,1],[0,4,2,0,0,0,0,0,9],[0,0,0,0,0,0,0,0,0],[0,0,7,6,0,0,8,0,0],[1,0,0,0,0,8,0,9,7],[3,0,0,4,0,0,0,0,0],[5,7,0,1,0,0,0,0,0],[4,0,0,0,0,0,9,0,8],[0,0,8,0,0,2,0,0,0]]
solveSudo(board)
print(board)

leetcode 209. 长度最小的子数组

发表于 2018-08-17 | 分类于 leetcode

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。

示例:

输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。

进阶:

  • 如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution:
def minSubArrayLen(self, s, nums):
"""
:type s: int
:type nums: List[int]
:rtype: int
"""
if not nums:return 0
if len(nums) == 1:
if nums[0] >= s:return 1
else:return 0
if sum(nums) < s:return 0
res = len(nums)
left ,right = 0,0
totalNum = 0
while right<len(nums):
totalNum += nums[right]
while totalNum >= s:
res = min(res,right-left+1)
if res == 1:return 1
totalNum -= nums[left]
left += 1
right += 1
return res

leetcode 208. 实现 Trie (前缀树)

发表于 2018-08-17 | 分类于 leetcode

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // 返回 true
trie.search("app");     // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");   
trie.search("app");     // 返回 true

说明:

  • 你可以假设所有的输入都是由小写字母 a-z 构成的。
  • 保证所有输入均为非空字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class TrieNode:
def __init__(self):
self.child = {}
self.end = False

class Trie:

def __init__(self):
"""
Initialize your data structure here.
"""
self.root = TrieNode()


def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: void
"""
current = self.root
for ch in word:
node = current.child.get(ch)
if not node:
node = TrieNode()
current.child[ch] = node
current = node
current.end = True

def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
curr = self.root
for ch in word:
if ch not in curr.child.keys():
return False
curr = curr.child[ch]
return curr.end

def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
curr = self.root
for ch in prefix:
if ch not in curr.child.keys():
return False
curr = curr.child[ch]
return True


# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

leetcode 207. 课程表

发表于 2018-08-15 | 分类于 leetcode

现在你总共有 n 门课需要选,记为 0 到 n-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

示例 1:

输入: 2, [[1,0]] 
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

示例 2:

输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

说明:

  • 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
  • 你可以假定输入的先决条件中没有重复的边。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import collections
class Solution(object):
def canFinish(self, numCourses, prerequisites):
"""
:type numCourses: int
:type prerequisites: List[List[int]]
:rtype: bool
"""
def movev(v,set1,set2):
set1.discard(v)
set2.add(v)

def dfs(v,white,grey,black):
movev(v,white,grey)
for i in d[v].keys():
if i in black:
continue
if i in grey:
return False
if not dfs(i,white,grey,black):
return False
movev(v,grey,black)
return True

d = collections.defaultdict(dict)
for i,j in prerequisites:
d[i][j] = 1
white = set(range(numCourses))
grey = set()
black = set()
for i in range(numCourses):
if not dfs(i,white,grey,black):return False
return True

leetcode 202. Happy Number

发表于 2018-08-14 | 分类于 leetcode

Write an algorithm to determine if a number is “happy”.

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example:

Input: 19
Output: true
Explanation: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution(object):
def isHappy(self, n):
#解决周期循环的问题可以使用快慢指针
def helper(n):
result = 0
while n != 0:
result += pow(n%10,2)
n = n//10
return result

r1 = helper(n)
r2 = helper(r1)
while r1 != 1:
if r1 == r2:
return False
r1 = helper(r1)
r2 = helper(helper(r2))
return True

leetcode 201. Bitwise AND of Numbers Range

发表于 2018-08-14 | 分类于 leetcode

Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

Example 1:

Input: [5,7]
Output: 4

Example 2:

Input: [0,1]
Output: 0
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution(object):
def rangeBitwiseAnd(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
i = 0
while n != m:
m >>= 1
n >>= 1
i += 1
return m << i

leetcode 297. 二叉树的序列化与反序列化

发表于 2018-08-14 | 分类于 leetcode

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

示例:

你可以将以下二叉树:

    1
   / \
  2   3
     / \
    4   5

序列化为 "[1,2,3,null,null,4,5]"

提示: 这与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Codec:
def __init__(self):
self.traversal = ""
self.index = 0

def _serialize(self, node):
if node is None:
self.traversal += 'null '
return

self.traversal += str(node.val) + ' '
self._serialize(node.left)
self._serialize(node.right)


def serialize(self, root):
"""Encodes a tree to a single string.

:type root: TreeNode
:rtype: str
"""
self._serialize(root)
return self.traversal


def _deserialize(self, data):
if self.index == len(data):
return None

if data[self.index] == 'null':
self.index += 1
return None

root = TreeNode(data[self.index])
self.index += 1
root.left = self._deserialize(data)
root.right = self._deserialize(data)
return root


def deserialize(self, data):
"""Decodes your encoded data to tree.

:type data: str
:rtype: TreeNode
"""
data = data.split(' ')
return self._deserialize(data)

leetcode 289. 生命游戏

发表于 2018-08-10 | 分类于 leetcode

根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  • 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  • 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
  • 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
  • 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
    根据当前状态,写一个函数来计算面板上细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。

示例:

输入: 
[
  [0,1,0],
  [0,0,1],
  [1,1,1],
  [0,0,0]
]
输出: 
[
  [0,0,0],
  [1,0,1],
  [0,1,1],
  [0,1,0]
]

进阶:

  • 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
  • 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution(object):
def gameOfLife(self, board):
if not board or not board[0]:
return
def getaliveneighbours(row,col):
return sum([1 for i,j in [(0,1),(0,-1),(1,0),(1,1),(1,-1),(-1,-1),(-1,1),(-1,0)] if (0<=row+i<len(board) and 0<=col+j<len(board[0]) ) and (board[row+i][col+j]==1 or board[row+i][col+j]==3)])

for i in range(len(board)):
for j in range(len(board[0])):
n = getaliveneighbours(i,j)
if board[i][j]==1 and 1<n<4:board[i][j]+=2
elif board[i][j]==0 and n==3:board[i][j]+=2
print(board)
for i in range(len(board)):
for j in range(len(board[0])):
board[i][j] = 1 if board[i][j]>1 else 0
print(board)
1…678…20

zhuanli

194 日志
9 分类
41 标签
GitHub
© 2018 — 2019 zhuanli
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4