类别:个人笔记
语言:python
内容:把一些简单的题目就说一下算法很好实现,没有一下想出来的或者看别人的才做出来的 详细写一下。主要是自己能看动,如果再能帮到别人就更好了。 自己的实现方法虽然在尽量减少挨个便利,但还是比较笨拙基础的。只适合刚入门的人看
自己写的
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i,num in enumerate(nums):
subnum = target - num
if subnum in nums:
index = nums.index(subnum)
if index != i:
return [i,index]
网上查的
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
n = len(numbers)
d = {}
for x in range(n):
a = target - numbers[x]
if numbers[x] in d:
return d[numbers[x]]+1,x+1
else:
d[a] = x
总结:in这个操作应该还是比较费时间,
第二段代码 例[2,7,11,16] 9 第一次循环 字典变为{'7':0} 就是把下标i的缺失值放入字典
当循环再次如果字典中有对应的key就可以 返回当前循环次数和字典value
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
y = int(x)
newInt = 0
if x < 0:
y = -y
while y != 0 :
i = y%10
newInt = newInt*10 +i
y = y//10
if newInt > 2**31-1:
return 0
if x < 0:
newInt = -newInt
return newInt
总结:比较简单 主意对负数的处理
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
res =''
tmp = re.findall('^[-+]?\d+',str.strip())#正则判断,非法字符串会返回空,返回的必是带有一个+/-或无符号的数字串
if tmp:
ms = tmp[0]
if ms[0] == "-" or ms[0] == "+":
res = ms[1:]
else:
res = ms
res = int(res)
if ms[0]== "-":
return max(-res,-0x80000000)
return min(res,0x7FFFFFFF)
else:
return 0
总结:正则判断省去许多麻烦,最后几行就是要求输出在整型范围内
总结:善于利用python的列表快捷操作
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
sArrayLen = len(strs)
if sArrayLen == 0:
return ""
index = 0;minValue = len(strs[0])
for i in range(sArrayLen):
if len(strs[i]) < minValue:
minValue = len(strs[i])
index = i
stringLen =len(strs[index])
if stringLen == 0:
return ""
for j in range(stringLen):
for i in range(sArrayLen):
if strs[index][:j+1] != strs[i][:j+1]:
return strs[0][:j]
return strs[index]
class Solution:
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummy = ListNode(0)
dummy.next = head
p1 = p2 = dummy
for i in range(n):
p1 = p1.next
while p1.next:
p1 = p1.next
p2 = p2.next
p2.next = p2.next.next
return dummy.next
总结:先让a指针跑N次 然后另一个指针b和a一起循环 a到最后的时候b 正好倒数第N个
这个方法自己创了个头节点 比我那个少了2个判断 简单一些
class Solution:
def removeDuplicates(self,nums):
"""
:type nums: List[int]
:rtype: int
"""
numLength = len(nums)
if nums == None or len(nums) < 0 :
return 0
j = 0
for i in range(numLength):
if nums[j] != nums[i]:
nums[j+1] = nums[i]
j += 1
nums = nums[:j+1]
return len(nums)
总结:原数组被破坏,其实返回j+1 就行。
移除元素和这道题类似,把所有和val不相等的放入下标j中,也是原地改写当前数组
class Solution:
def countAndSay(self, n):
"""
:type n: int
:rtype: str
"""
count = "1"
a = count[0]
for i in range(n-1):
mapCount = {}
countNew = ""
index = len(count) - 1
j = 0
for q in range(len(count)):
if j == 0 :
mapCount[count[j]] = 1
if len(count) > 1:
j += 1
continue
else:
countNew += str(mapCount.pop(count[j])) + count[j]
continue
if count[j] == count[j-1] and j > 0:
mapCount[count[j]] += 1
else:
countNew += str(mapCount.pop(count[j-1])) + count[j-1]
mapCount[count[j]] = 1
if j + 1 == len(count):
countNew += str(mapCount.pop(count[j])) + count[j]
continue
j += 1
count = countNew
return count
总结:循环上一个数 如果连续相同 就在字典中把值加1 如果遇到不同就把字典中的内容按value key输出
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
numsLen = len(nums)
if numsLen == 0 or nums == None:
return None
start = 0
maxSum = 0;maxNum = nums[0]
sum = 0
for i in range(numsLen):
if maxNum < nums[i]:
maxNum = nums[i]
sum += nums[i]
if sum > maxSum:
maxSum = sum
elif sum < 0:
sum = 0
if maxSum == 0:
return maxNum
return maxSum
总结: 一旦前n个和是负数 那么 前n个和 加 第n+1个数的值 一定小于第n+1个数。所以一旦小于0就重新计算
如果整数数组都为负就返回最大值
class Solution:
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
resultList = []
tempList = []
for i in range(numRows):
newList = list(range(i+1))
for j in range(i+1):
if j == 0 or j == i:
newList[j] = 1
else:
newList[j] = tempList[j] + tempList[j-1]
tempList = newList
resultList.append(tempList)
return resultList
总结:第一个和最后一个永远为1.保存上一层的内容 求出这一层的内容 然后循环
class Solution:
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if nums == None or len(nums) < 0 :
return 0
result = 0
for i in nums:
result = result^i
return result
总结:根据异或定义 0^n = n n^n = 0 不管顺序只要出现过2次的全会变为0 最终结果即为所求
对^ & >> 等操作还要加强熟练
class Solution:
def trailingZeroes(self, n):
"""
:type n: int
:rtype: int
"""
count = 0
while n >= 5:
count += n//5
n = n // 5
return count
总结:观察的结果 本来以为阶乘中有个5就会多一个0, 但25之后发现又额外多了一个。因为25 是 5×5 所以就会额外多0
所以就去找n‘包含5’的个数
class Solution:
# @param n, an integer
# @return an integer
def reverseBits(self, n):
result = 0
for i in range(32):
# 二进制里面从低位取得时候就同或
result = result << 1 ^ (n&1)
n = n >> 1
return result
总结: n&1 就是取最低位 其次用result << 1和最低位异或 就是把最低位放入result的最低位。之前答案一直不对是因为循环次数应该固定32
注:汉明重量(数字2进制位1的个数) count += n&1 就是最后一位的数字循环计算
class Solution:
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
isPrime = [True] * max(n, 2)
isPrime[0], isPrime[1] = False, False
x = 2
while x * x < n:
if isPrime[x]:
p = x * x
while p < n:
isPrime[p] = False
p += x
x += 1
return sum(isPrime)
总结:思路是一样的筛选法,但实现起来比我的简便的很多。而且他开始的地方是x*x 因为前面小于x*x的 非质数已经被过滤掉了
class Solution:
def isPowerOfTwo(self, n):
"""
:type n: int
:rtype: bool
"""
if n == 0:
return False
n = n & (n-1)
if n == 0:
return True
return False
总结:凡是2的幂 二进制序列一定只有一个1,其他都会有多个1。n&(n-1)这个操作就是找1的数量 。汉明距离也用这个方法
class Solution:
def addDigits(self, num):
"""
:type num: int
:rtype: int
"""
if num < 10:
return num
return (num-1)%9 + 1
总结:12623 = (1 + 2 + 6 + 2 + 3) + 1 × 9999 + 2 × 999 + 6 ×99 + 2 ×9 而 1 + 2 + 6 + 2 + 3 = 14 = 1 ×9 + 4 + 1 所以只要%9 就是最后的结果 12623 => 14 => 5
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
for i in range(len(s)):
char = s[i]
newS = s[0:i] + s[i+1:]
if char not in newS:
return i
return -1
总结:截取以后并没有赋值给原数组,只是单蠢的截取判断
1.20.有效括号 就是循环判断 一遇到反括号 就pop 如果对应就继续循环不对应 return False
2. 21.合并有序链表 值比较 放入新列表
3.28.实现 strStr() haystack.split(needle) 能拆分ture 不能false
4.35.搜索插入位置 循环判断
5.36.有效数独 各种判断 具体代码网上抄的
6.48.旋转图像 先上下翻转 再对角线翻转 python的好处就是 交换赋值简单
7.58.最后一个单词的长度newStr = s.strip().split(' ')[-1]
8.66.加一 从最后一位往前循环判断是不是9 是的话变0 继续循环
9.67.二进制求和 python二进制求和很简单bin(int(a,2) + int(b,2))[2:] 就是把字符串二进制转成10进制 相加再转回来 把前缀去了
10.70.核心代码result.append(result[i-1]+result[i-2]) 费伯纳西数列? 记不太清了 反正我是列了前10个找规律 也可以用递归
11.121.买卖股票的最佳时机 基本上就是设定一个最小值 然后 下一个数大 计算利润和最大利润比较 小的话就设为新的最小值
12.125.验证回文串 核心代码s[i].isalnum()组成一个新数组
13.141.环形链表 就是快慢指针 一个next一下 一个next2下 如果出现 nodeSlow == NodeFast 就是出现环了。 快慢指针在很多地方都能用,比如求中点,计算倒数第几个
14.189.旋转数组 刚开始对原地没有概念 提交错了很多次。 而且list的del函数是原地操作 我不知道这个函数的效率和一个一个慢慢移哪个快 反正我就直接del了。。 我也在网上查了一下 有递归 还有一个copy方法 都不好 要求是原地算法 而且递归真的是没有办法的时候再用,虽然代码短但是真的性能差啊 面试的时候喜欢递归的有一个毙一个
15.202.快乐数 常规除模操作 就是有部判断 非快乐数最终会陷入一个固定的循环 找到规律return false 例 if n == 145:return False
16.206.翻转列表 头插法
17.234.回文链表 快慢指针找到中点 把中点后的头插法和 前面的比较
18.242.有效的字母异词位 344.反转字符串 合理利用python list的强大功能[:]我也不知道这个专业名字叫什么
19.263.丑数 循环判断就行
20.268.缺失数字 和Single Number一个道理 把缺失数字numbers和list(range(len(nums)))异或一下
21.349.两个数组的交集 set 一下 &一下 就是求交集 然后再转成list
22.350.两个数组的交集 383.赎金信 类似就是判断完之后记得截取剩下内容 继续判断