Zhuanli&Blog


  • 首页

  • 标签

  • 分类

  • 归档

leetcode 328. 奇偶链表

发表于 2018-07-09 | 分类于 leetcode

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL

示例 2:

输入: 2->1->3->5->6->4->7->NULL 
输出: 2->3->6->7->1->5->4->NULL

说明:

  • 应当保持奇数节点和偶数节点的相对顺序。
  • 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。
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
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution(object):
def oddEvenList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:return head
odd_cur = head
even_head = head.next
even_cur = even_head
while even_cur and even_cur.next:
next_odd = even_cur.next
next_even = even_cur.next.next
odd_cur.next = next_odd
even_cur.next = next_even
odd_cur = odd_cur.next
even_cur = even_cur.next
odd_cur.next = even_head
return head

python创建二维数组的正确姿势

发表于 2018-07-06 | 分类于 python

今天做leetcode题的时候,需要创建一个二维数组(m,n)(m表示行,n表示列),我是这样创建的:

1
matrix = [[0]*n]*m

测试算法结果的时候无论怎么测结果都是错的,找了半天没有找到错误,之后打印二维数组的值多次后发现matrix[0]…matrix[m-1]的值是一模一样的,查了资料之后知道了这样创建的二维数组复制了m个相同的数组,当你修改其中一个时,另外的值也会被改变。

正确的创建数组的方式:

1
matrix = [[0 for i in range(n)] for _ in range(m)]

一个更加简短的创建方式也是可以的:

1
matrix = [[0]*n for _ in range(m)]

leetcode 329. 矩阵中的最长递增路径

发表于 2018-07-06 | 分类于 leetcode

给定一个整数矩阵,找出最长递增路径的长度。

对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。

示例 1:

输入: nums = 
[
  [9,9,4],
  [6,6,8],
  [2,1,1]
] 
输出: 4 
解释: 最长递增路径为 [1, 2, 6, 9]。

示例 2:

输入: nums = 
[
  [3,4,5],
  [3,2,6],
  [2,2,1]
] 
输出: 4 
解释: 最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution(object):
def longestIncreasingPath(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: int
"""
memo={}
def helper(i,j):
if (i,j) in memo:
return memo[(i,j)]
ans=1
for k1,k2 in [[0,1],[0,-1],[1,0],[-1,0]]:
if 0<=i+k1<len(matrix) and 0<=j+k2<len(matrix[0]) and matrix[i][j]>matrix[i+k1][j+k2]:
ans=max(ans,1+helper(i+k1,j+k2))
memo[(i,j)]=ans
return ans
ans=0
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if (i,j) not in memo:
ans=max(ans,helper(i,j))
return ans

leetcode 330. 按要求补齐数组

发表于 2018-07-05 | 分类于 leetcode

给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。

示例 1:

输入: nums = [1,3], n = 6
输出: 1 
解释:
根据 nums 里现有的组合 [1], [3], [1,3],可以得出 1, 3, 4。
现在如果我们将 2 添加到 nums 中, 组合变为: [1], [2], [3], [1,3], [2,3], [1,2,3]。
其和可以表示数字 1, 2, 3, 4, 5, 6,能够覆盖 [1, 6] 区间里所有的数。
所以我们最少需要添加一个数字。

示例 2:

输入: nums = [1,5,10], n = 20
输出: 2
解释: 我们需要添加 [2, 4]。

示例 3:

输入: nums = [1,2,2], n = 5
输出: 0
  • mysolution
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
def greedy(nums,n):
needed = set(range(1,n+1))#all need to
covered = set()#cover to all
tmpcover = []
full = []
for i in nums:
if i <= n:full.append(i)
pick = needed-set(full)#can choose num
for i in full:
for j in covered:
tmpcover.append(i+j)
tmpcover.append(i)
covered = set(tmpcover)
needed -= covered
count = 0
while needed:
state_covered = set()
k = 0
for i in pick:#find suitable picknum to maxsuit needed
tmpcover = []
for j in covered:
tmpcover.append(i+j)
tmpcover.append(i)
state_covered = set(tmpcover)
state_covered = needed&state_covered
if len(state_covered) > k:
k = len(state_covered)
covered = state_covered
needed -= covered
count += 1
return count
  • clear solution
1
2
3
4
5
6
7
8
9
10
def greedy(nums,n):
miss,added,i=1,0,0
while miss <= n:
if i < len(nums) and nums[i] <= miss:
miss += nums[i]
i += 1
else:
miss += miss
added += 1
return added

leetcode 331. 验证二叉树的前序序列化

发表于 2018-07-04 | 分类于 leetcode

序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。

     _9_
    /   \
   3     2
  / \   / \
 4   1  #  6
/ \ / \   / \
# # # #   # #

例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#'。

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。

示例 1:

输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true

示例 2:

输入: "1,#"
输出: false

示例 3:

输入: "9,#,#,1"
输出: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution(object):
def isValidSerialization(self, preorder):
"""
:type preorder: str
:rtype: bool
"""
diff = 1
prelist = preorder.split(',')
for node in prelist:
diff -= 1
if diff < 0:return False
if node != '#':
diff += 2
return diff == 0

c/c++调试工具gdb使用

发表于 2018-07-03 | 分类于 linux

gdb之前

gdb是gcc的调试工具,主要用于c/c++这两种语言的编程的调试。功能强大,主要体现在以下几点:

  • 可以按照用户自定义的要求随心所欲的运行程序
  • 可以设置断点,让程序在断点处停住
  • 当程序停住时,可以检查此时程序中运行状态

要调试程序,首先在编译的时候,必须把调试信息加到可执行文件中,使用gcc/g++ 的-g参数可以做到,如下:

1
gcc -g -o hello hello.cpp

启动gdb的方法:

1
gdb hello

hello是你的执行文件,一般在当前目录下

一个例子

接下来看一个例子

1
2
3
4
5
6
7
8
9
10
#include <iostream>
int main()
{
int a = 1;
a = a + 6;
char p[] = "you are amazing";
std::cout<<p<<std::endl;
std::cout<<"hello world\n";
return 0;
}

使用

1
gcc -g -o hello hello.cpp

编译之后,输入gdb hello,启动gdb。
结果如图1 如图1 启动
图1 启动

输入l,表示list,从第一行开始列出源码,如图2,再按下enter键,表示重复上一次命令
如图2 列出源码
图2 列出源码

执行’b 6‘表示设置再源码6行处设置断点,执行‘b main’表示再main函数处设置断点,执行‘info break’表示查看断点信息,图3 如图3 断点
图3 断点

执行r命令,表示运行程序图4 如图4 运行
图4 运行

输入n表示单条语句执行,输入p a,p p表示分别打印a的值和p数组的值,打印ascii码值,输入x/s p,输入bt查看函数堆栈,图5如图5 显示
图5 显示

输入finish推出函数,输入q结束调试。

总结

上面的例子一个使用了以下命令:l,b,r,n,p,bt,x/s,finish,q,调试一些简单的程序已经够用了,但是想要更加深入了解gdb,可以参考链接

leetcode 332. Reconstruct Itinerary

发表于 2018-07-03 | 分类于 leetcode

Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK.

Note:

  • If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"].
  • All airports are represented by three capital letters (IATA code).
  • You may assume all tickets form at least one valid itinerary.

Example 1:

Input: tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Output: ["JFK", "MUC", "LHR", "SFO", "SJC"]

Example 2:

Input: tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
Output: ["JFK","ATL","JFK","SFO","ATL","SFO"]
Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. But it is larger in lexical order.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import heapq
import collections
class Solution(object):
def findItinerary(self, tickets):
"""
:type tickets: List[List[str]]
:rtype: List[str]
"""
if not tickets:return []
dic = collections.defaultdict(list)
res = []
for fr,to in tickets:
heapq.heappush(dic[fr],to)
def dfs(city):
if city in dic:
while dic[city]:
dfs(heapq.heappop(dic[city]))
res.append(city)
dfs('JFK')
return res[::-1]

leetcode 334. 递增的三元子序列

发表于 2018-07-02 | 分类于 leetcode

给定一个未排序的数组,请判断这个数组中是否存在长度为3的递增的子序列。

正式的数学表达如下:

如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1,
使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。
要求算法时间复杂度为O(n),空间复杂度为O(1) 。

示例:

输入 [1, 2, 3, 4, 5],
输出 true.

输入 [5, 4, 3, 2, 1],
输出 false.

like #最长递增子序列 的特殊情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import bisect
class Solution(object):
def increasingTriplet(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
res = [float("inf")]*2
for i in nums:
index = bisect.bisect_left(res,i)
if index == 2:
return True
res[index] = i
return False

a clear solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution(object):
def increasingTriplet(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
c1,c2 = float('inf'),float('inf')
for n in nums:
if n <= c1:
c1 = n
elif n <= c2:
c2 = n
else:
return True
return False

leetcode 335. Self Crossing

发表于 2018-06-29 | 分类于 leetcode

给定一个含有 n 个正数的数组 x。从点(0,0)开始,向北移动x[0]米,然后向西移动x[1]米,向南移动x[2]米,向东移动x[3]米,持续进行。换句话说,每次移动后你的方向都会逆时针变化。

以 O(1)的空间复杂度写一个一遍扫描算法,判断你的路径是否交叉。

示例 1:

给定 x = [2, 1, 1, 2],
?????
?   ?
???????>
    ?

返回 true (路径交叉了)

示例 2:

给定 x = [1, 2, 3, 4],
????????
?      ?
?
?
?????????????>

返回 false (路径没有相交)

示例 3:

给定 x = [1, 1, 1, 1],
?????
?   ?
?????>

返回 true (路径相交了)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution(object):
def isSelfCrossing(self, x):
"""
:type x: List[int]
:rtype: bool
"""
n = len(x)
if n < 4:
return False

i = 3
while i < n:
if x[i] >= x[i - 2] and x[i - 1] <= x[i - 3]:
return True
if i >= 4:
if x[i - 1] == x[i - 3] and x[i] + x[i - 4] >= x[i - 2]:
return True
if i >= 5:
if x[i] >= x[i - 2] - x[i - 4] >= 0 and x[i - 3] - x[i - 5] <= x[i - 1] <= x[i - 3]:
#if x[i] + x[i - 4] >= x[i - 2] and x[i - 3] <= x[i - 5] + x[i - 1]:
return True
i += 1
return False

leetcode 336. 回文对

发表于 2018-06-28 | 分类于 leetcode

给定一组独特的单词, 找出在给定列表中不同 的索引对(i, j),使得关联的两个单词,例如:words[i] + words[j]形成回文。

示例 1:
给定 words = ["bat", "tab", "cat"]
返回 [[0, 1], [1, 0]]
回文是 ["battab", "tabbat"]

示例 2:
给定 words = ["abcd", "dcba", "lls", "s", "sssll"]
返回 [[0, 1], [1, 0], [3, 2], [2, 4]]
回文是 ["dcbaabcd", "abcddcba", "slls", "llssssll"]`

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
class Solution(object):
def palindromePairs(self, words):
"""
:type words: List[str]
:rtype: List[List[int]]
"""
def is_reverse(word):
return word==word[::-1]

words = {word:k for k,word in enumerate(words)}
res = []
for word,k in words.iteritems():
n = len(word)
for i in range(n+1):
pre = word[:i]
suf = word[i:]
if is_reverse(pre):
back = suf[::-1]
if back != word and back in words:
res.append([words[back],k])
if i != n and is_reverse(suf):
back = pre[::-1]
if back != word and back in words:
res.append([k,words[back]])
return res
1…101112…20

zhuanli

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