心得:想清楚,打草稿,避免不必要的错误
记录是否进位
class Solution: # @param {integer[]} digits # @return {integer[]} def plusOne(self, digits): i, carry = -1, True while(carry): if digits[i]==9: digits[i] = 0 if i==-len(digits): digits = [1] + digits carry = False i -= 1 else: digits[i] += 1 carry = False return digits
是九变0,最高位加[1]
class Solution: # @param {integer[]} digits # @return {integer[]} def plusOne(self, digits): i = -1 while(not i<-len(digits)): if digits[i] != 9: digits[i] += 1 return digits else: digits[i] = 0 i -= 1 digits = [1] + digits return digits
使用del删除list里的元素
class Solution: # @param {integer[]} nums # @return {integer} def removeDuplicates(self, nums): i, j = 0, 1 if len(nums)<2: return len(nums) while(i < len(nums)-1): j = i+1 if nums[i] == nums[j]: del nums[j] else: i += 1 return len(nums)
不改变list
class Solution: # @param {integer[]} nums # @return {integer} def removeDuplicates(self, nums): l, i = 1, 1 if len(nums)<2: return len(nums) for i in range(1,len(nums)): if nums[i]!=nums[i-1]: nums[l] = nums[i] l += 1 return l
利用Python的list comprehension想写出一行代码
class Solution: # @param {integer[]} nums # @param {integer} val # @return {integer} def removeElement(self, nums, val): # nums = [x for x in nums if x!=val] z = [y for y in nums if y != val] for k,v in enumerate(z): nums[k] = v return len(z)
但是题目要求要在原地修改list的内容,所以原来就想着直接给nums赋值,结果大错特错!
问题在于,Python中的Naming是将一个名字和一个Object绑定即binding,而不是以前的assign。带图的解释戳这里
而且Python的binding是有作用域的,即scope。在一个作用域里的绑定是不会在子作用域里被改变的。
在这里就是,大环境下绑定了nums(原),而在函数中重新建立了一个list并用nums(新)去绑定了。当函数执行完毕之后,回到大环境下,nums其实还是nums(原),所以之前的写法会错。
这一段论述可以由下图验证:
那这样的解决办法就是在函数中,给nums(原)绑定的对重写。即for k,v in enumerate(z): nums[k] = v。
利用此题中众数次数超过一半的特性 O(n)
class Solution: # @param {integer[]} nums # @return {integer} def majorityElement(self, nums): count, temp = 1, nums[0] for x in nums[1:]: if x==temp: count += 1 else: count -= 1 if count==0: temp = x count = 1 return temp
哈希表 O(n)
位操作 O(n)
class Solution: # @param {integer[]} nums # @return {boolean} def containsDuplicate(self, nums): pos, neg = 0, 0 for x in nums: if x < 0: temp = 1 << -x if neg & temp != 0: return True pos |= temp else: temp = 1 << x if pos & temp != 0: return True pos |= temp return False
哈希表 O(n)
Python一行
ComposingPrograms 1.7 Exercises
def countdown(n): print(n) if n>1: countdown(n-1) def countup(n): if n>0: countup(n-1) print(n) def recursive(m,n): if n>0: return m + recursive(m, n-1) else: return 0 def expt(base, power): if power==0: return 1 else: return base * expt(base, power-1) def sum_digits(n): if n<10: return n else: return n%10 + sum_digits(n//10) def is_prime(n, d): if n<=1: return False elif d==1: return True elif n%d==0: return False else: return is_prime(n, d-1) def sum_primes_up_to(n): if n==2: return 2 elif is_prime(n, n-1): return sum_primes_up_to(n-1) + n else: return sum_primes_up_to(n-1)
这里用python做一个mutual recursion
def split(n): return n//10, n%10 def luhn_sum(n): if n<10: return n else: rest, last = split(n) return luhn_double_sum(rest) + last def luhn_double_sum(n): rest, last = split(n) luhn_digit = split(2*last)[0] + split(2*last)[1] if n<10: return luhn_digit else: rest, last = split(n) return luhn_sum(rest) + luhn_digit
寻找函数零点:Quickly finds accurate approximations to zeros of differenciable functions.
只要问题是可微的,则问题是可解的。
Wikipedia上操作演示
https://en.wikipedia.org/wiki/Newton's_method#/media/File:NewtonIteration_Ani.gif
实现指南:
高阶函数为的是抽象出功能,不要被参数混乱思路
python中整数相除会返回整数,所以注意传入浮点数做参数
def square_root(a): def f(x): return x * x - a def df(x): return 2 * x return find_zero(f, df) def find_zero(f, df): def near_zero(x): return appro_equal(f(x), 0) return improve(update(f, df), near_zero, guess=1.0, max_update=100) def update(f, df): def u(x): return x - f(x)/df(x) return u def improve(update, close, guess, max_update): k = 0 while not close(guess) and k < max_update: print guess, k guess = update(guess) k += 1 return guess # the guess improved def appro_equal(x, y, tolerance=1e-15): print abs(x-y) < tolerance return abs(x-y) < tolerance
推广至求n次根
>>> def power(x, n): """Return x * x * x * ... * x for x repeated n times.""" product, k = 1, 0 while k < n: product, k = product * x, k + 1 return product >>> def nth_root_of_a(n, a): def f(x): return power(x, n) - a def df(x): return n * power(x, n-1) return find_zero(f, df)
实际应用 Function Decorator
def trace(fn): def t(x): print "Calling", fn, "on argument", x return fn(x) return t @trace def square(x): return x * x
学习资料:
http://composingprograms.com/pages/16-higher-order-functions.html
定义:
Higher-Order functions can accept other functions as arguments or return functions as values.
例一:计算黄金比例
def improve(update, close, guess=1): while not close(guess): guess = update(guess) return guess def golden_update(guess): return 1/guess + 1 def square_close_to_successor(guess): return approx_eq(guess * guess, guess + 1) def approx_eq(x, y, tolerance=1e-3): return abs(x - y) < tolerance phi = improve(golden_update, square_close_to_successor)
Two key advantages of lexical scoping in Python.
例二:
def average(x, y): return (x + y)/2 def improve(update, close, guess=1): while not close(guess): guess = update(guess) return guess def approx_eq(x, y, tolerance=1e-3): return abs(x - y) < tolerance def sqrt(a): def sqrt_update(x): return average(x, a/x) def sqrt_close(x): return approx_eq(x * x, a) return improve(sqrt_update, sqrt_close) result = sqrt(256) |
函数计算时层层隔离,名字重复无影响。但是对于大工程来说,明明冲突可能给自己带来麻烦,比如需要重命名的时候。
def square(x): return x * x def successor(x): return x + 1 def compose1(f, g): def h(x): return f(g(x)) return h def f(x): """Never called.""" return -x square_successor = compose1(square, successor) result = square_successor(12)