python中怎样找出递增子序列_Python中最长的递增子序列(For vs While循环)

我正在解决这个leetcode问题link,我们应该在其中找到列表或数组中最长的递增子序列.我使用解决了问题

两种方法.

>首先使用while循环

>使用嵌套的for循环

Even though the value of (i, j) or looping is exactly same, but for

the higher length inputs, the while loop program is taking more time

than the for program. I am not sure why?

为循环

import time

start_time = time.time()

class Solution(object):

# using dP

def lengthOfLIS1(self, nums):

"""

:type nums: List[int]

:rtype: int

"""

if not nums:

return 0

dp = [1] * len(nums)

for i in range(1, len(nums)):

for j in range(i):

if nums[i] > nums[j]:

dp[i] = max(dp[i], dp[j] + 1)

return max(dp)

print Solution().lengthOfLIS1([1] * 1249 + [101] + [1] * 1250)

print("--- %s seconds ---" % (time.time() - start_time))

输出:

2

--- 0.240112066269 seconds ---

循环时

# This problem an be done in O(n*n)

import time

start_time = time.time()

class Solution(object):

def lengthOfLIS(self, nums):

"""

:type nums: List[int]

:rtype: int

"""

if not nums:

return []

elif len(nums) == 1:

return nums

size = len(nums)

subsequence_array = [1] * size

i, j, max_value = 0, 1, 1

while j < size:

if nums[j] > nums[i]:

subsequence_array[j] = max(subsequence_array[j], subsequence_array[i] + 1)

if max_value < subsequence_array[j]:

max_value = subsequence_array[j]

i += 1

if j == i:

i = 0

j += 1

else:

i += 1

if i == j:

j += 1

i = 0

return max_value

print Solution().lengthOfLIS([1] * 1249 + [101] + [1] * 1250)

print("--- %s seconds ---" % (time.time() - start_time))

输出值

2

--- 0.331799030304 seconds ---

谁能解释为什么while循环比for循环花费更多的时间,即使i和j的循环几乎相同?将感谢您的回答.

解决方法:

看一下字节码

while循环必须执行更多操作.

Python正在执行字节码.因此,字节码指令的数量和种类可以提示您实际发生的情况.

Dis模块中的功能dis:

import dis

可以形象地显示bytcode.

首先是范围解决方案:

dis.dis(SolutionRange)

Disassembly of lengthOfLIS1:

8 0 LOAD_FAST 1 (nums)

3 POP_JUMP_IF_TRUE 10

9 6 LOAD_CONST 1 (0)

9 RETURN_VALUE

10 >> 10 LOAD_CONST 2 (1)

13 BUILD_LIST 1

16 LOAD_GLOBAL 0 (len)

19 LOAD_FAST 1 (nums)

22 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

25 BINARY_MULTIPLY

26 STORE_FAST 2 (dp)

11 29 SETUP_LOOP 103 (to 135)

32 LOAD_GLOBAL 1 (range)

35 LOAD_CONST 2 (1)

38 LOAD_GLOBAL 0 (len)

41 LOAD_FAST 1 (nums)

44 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

47 CALL_FUNCTION 2 (2 positional, 0 keyword pair)

50 GET_ITER

>> 51 FOR_ITER 80 (to 134)

54 STORE_FAST 3 (i)

12 57 SETUP_LOOP 71 (to 131)

60 LOAD_GLOBAL 1 (range)

63 LOAD_FAST 3 (i)

66 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

69 GET_ITER

>> 70 FOR_ITER 57 (to 130)

73 STORE_FAST 4 (j)

13 76 LOAD_FAST 1 (nums)

79 LOAD_FAST 3 (i)

82 BINARY_SUBSCR

83 LOAD_FAST 1 (nums)

86 LOAD_FAST 4 (j)

89 BINARY_SUBSCR

90 COMPARE_OP 4 (>)

93 POP_JUMP_IF_FALSE 70

14 96 LOAD_GLOBAL 2 (max)

99 LOAD_FAST 2 (dp)

102 LOAD_FAST 3 (i)

105 BINARY_SUBSCR

106 LOAD_FAST 2 (dp)

109 LOAD_FAST 4 (j)

112 BINARY_SUBSCR

113 LOAD_CONST 2 (1)

116 BINARY_ADD

117 CALL_FUNCTION 2 (2 positional, 0 keyword pair)

120 LOAD_FAST 2 (dp)

123 LOAD_FAST 3 (i)

126 STORE_SUBSCR

127 JUMP_ABSOLUTE 70

>> 130 POP_BLOCK

>> 131 JUMP_ABSOLUTE 51

>> 134 POP_BLOCK

15 >> 135 LOAD_GLOBAL 2 (max)

138 LOAD_FAST 2 (dp)

141 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

144 RETURN_VALUE

现在为一会儿解决方案:

dis.dis(SolutionWhile)

Disassembly of lengthOfLIS:

7 0 LOAD_FAST 1 (nums)

3 POP_JUMP_IF_TRUE 10

8 6 BUILD_LIST 0

9 RETURN_VALUE

9 >> 10 LOAD_GLOBAL 0 (len)

13 LOAD_FAST 1 (nums)

16 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

19 LOAD_CONST 1 (1)

22 COMPARE_OP 2 (==)

25 POP_JUMP_IF_FALSE 32

10 28 LOAD_FAST 1 (nums)

31 RETURN_VALUE

12 >> 32 LOAD_GLOBAL 0 (len)

35 LOAD_FAST 1 (nums)

38 CALL_FUNCTION 1 (1 positional, 0 keyword pair)

41 STORE_FAST 2 (size)

13 44 LOAD_CONST 1 (1)

47 BUILD_LIST 1

50 LOAD_FAST 2 (size)

53 BINARY_MULTIPLY

54 STORE_FAST 3 (subsequence_array)

14 57 LOAD_CONST 3 ((0, 1, 1))

60 UNPACK_SEQUENCE 3

63 STORE_FAST 4 (i)

66 STORE_FAST 5 (j)

69 STORE_FAST 6 (max_value)

15 72 SETUP_LOOP 172 (to 247)

>> 75 LOAD_FAST 5 (j)

78 LOAD_FAST 2 (size)

81 COMPARE_OP 0 (

84 POP_JUMP_IF_FALSE 246

16 87 LOAD_FAST 1 (nums)

90 LOAD_FAST 5 (j)

93 BINARY_SUBSCR

94 LOAD_FAST 1 (nums)

97 LOAD_FAST 4 (i)

100 BINARY_SUBSCR

101 COMPARE_OP 4 (>)

104 POP_JUMP_IF_FALSE 205

17 107 LOAD_GLOBAL 1 (max)

110 LOAD_FAST 3 (subsequence_array)

113 LOAD_FAST 5 (j)

116 BINARY_SUBSCR

117 LOAD_FAST 3 (subsequence_array)

120 LOAD_FAST 4 (i)

123 BINARY_SUBSCR

124 LOAD_CONST 1 (1)

127 BINARY_ADD

128 CALL_FUNCTION 2 (2 positional, 0 keyword pair)

131 LOAD_FAST 3 (subsequence_array)

134 LOAD_FAST 5 (j)

137 STORE_SUBSCR

18 138 LOAD_FAST 6 (max_value)

141 LOAD_FAST 3 (subsequence_array)

144 LOAD_FAST 5 (j)

147 BINARY_SUBSCR

148 COMPARE_OP 0 (

151 POP_JUMP_IF_FALSE 164

19 154 LOAD_FAST 3 (subsequence_array)

157 LOAD_FAST 5 (j)

160 BINARY_SUBSCR

161 STORE_FAST 6 (max_value)

20 >> 164 LOAD_FAST 4 (i)

167 LOAD_CONST 1 (1)

170 INPLACE_ADD

171 STORE_FAST 4 (i)

21 174 LOAD_FAST 5 (j)

177 LOAD_FAST 4 (i)

180 COMPARE_OP 2 (==)

183 POP_JUMP_IF_FALSE 243

22 186 LOAD_CONST 2 (0)

189 STORE_FAST 4 (i)

23 192 LOAD_FAST 5 (j)

195 LOAD_CONST 1 (1)

198 INPLACE_ADD

199 STORE_FAST 5 (j)

202 JUMP_ABSOLUTE 75

25 >> 205 LOAD_FAST 4 (i)

208 LOAD_CONST 1 (1)

211 INPLACE_ADD

212 STORE_FAST 4 (i)

26 215 LOAD_FAST 4 (i)

218 LOAD_FAST 5 (j)

221 COMPARE_OP 2 (==)

224 POP_JUMP_IF_FALSE 75

27 227 LOAD_FAST 5 (j)

230 LOAD_CONST 1 (1)

233 INPLACE_ADD

234 STORE_FAST 5 (j)

28 237 LOAD_CONST 2 (0)

240 STORE_FAST 4 (i)

>> 243 JUMP_ABSOLUTE 75

>> 246 POP_BLOCK

30 >> 247 LOAD_FAST 6 (max_value)

250 RETURN_VALUE

while解决方案中还有更多行字节码.这表明速度较慢.当然,并非所有字节码指令都花相同的时间,并且需要进行更深入的分析以获得更定量的答案.

一切都是对象

在Python中,一切都是对象.因此,这:

>>> 1 + 1

2

实际上是这样做的:

>>> 1 .__add__(1)

2

因此,两个整数的简单加法涉及对方法__add __()的调用.这样的通话相对较慢.

例如,我们有以下列表:

L = list(range(int(1e6)))

内置函数sum()的和:

%%timeit

sum(L)

100 loops, best of 3: 15.9 ms per loop

比编写循环快得多:

%%timeit

sum_ = 0

for x in L:

sum_ += x

10 loops, best of 3: 95.7 ms per loop

内置总和使用的优化避免了“一切都是对象”概念引起的一些开销.

while解决方案具有许多运算,例如j =1.这些运算本身会增加可测量的执行时间.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值