1、根据数字返回相应位置数字
def get_digit(num, i):
# i=0 个位 1 十位 2 百位...
return num // (10 ** i) % 10
# print(get_digit(12345, 6))
2、列表反转,不用内置函数
def reverse_list(li):
n = len(li)
for i in range(n // 2):
li[i], li[n-i-1] = li[n-i-1], li[i]
return li
# print(reverse_list([1,2,3,4,5,6]))
3、数字反转,不用切片,不用内置函数
# 123->321 12300->321
def reverse_int(num):
is_neg = False
if num < 0:
is_neg = True
num = -1 * num
res = 0
while num > 0:
res = res * 10
res += num % 10
num = num // 10
if is_neg:
res = res * -1
return res
# print(reverse_int(-123001))
4、数字转列表
def int2list(num):
li = []
while num > 0:
li.append(num % 10)
num = num // 10
li.reverse()
return li
# print(int2list(123456))
5、一段n个台阶组成的楼梯,小明从楼梯的最底层向最高层处前进,他可以一次迈一阶或两阶,问:他有多少种不同的走法?
def func(n):
if n==0 or n==1:
return 1
else:
return f(n-1)+f(n-2)
6、按照单词反转给定句子。例如,输入"what is your name",返回"name your is what"。请不要使用诸如''.split, [::-1]等时间/空间复杂度不是O(1)的函数
def str_reverse(str,i,j):
while i<j:
str[i],str[j]=str[j],str[i]
i+=1
j-=1
def sentence_reverse(sentence):
sent_list = list(sentence)
i=0
len_list = len(sent_list)
while i<len_list:
if sent_list[i] !=' ':
start = i
end=start+1
while (end<len_list) and (sent_list[end]!=' '):
end += 1
str_reverse(sent_list,start,end-1)
i = end
else:
i+=1
sent_list.reverse()
return(''.join(sent_list))
栈,队列相关
括号匹配问题:给一个字符串,其中包含小括号、中括号、大括号,求该字符串中的括号是否匹配
def brace_match(s):
stack = []
d = {'(':')', '[':']', '{':'}'}
for ch in s:
if ch in {'(', '[', '{'}:
stack.append(ch)
elif len(stack) == 0:
print('多了右括号%s' % ch)
return False
elif d[stack[-1]] == ch:
stack.pop()
else:
print('括号%s处不匹配' % ch)
return False
if len(stack) == 0:
return True
else:
print("剩余左括号未匹配")
return False
print(brace_match('[]{{}[]{()})}'))
用两个栈实现队列
class QueueStack(object):
def __init__(self):
self.l1 = []
self.l2 = []
def push(self,a):
self.l1.append(a)
def pop(self):
if not self.l2:
for i in range(len(self.l1)):
a = self.l1.pop()
self.l2.append(a)
if self.l2:
return self.l2.pop()
else:
return False
一行代码模拟 Linux 中的 tail
# import queue # 不能设置大小
from collections import deque
# q = deque() # 双向队列,可以设置大小,超过大小,后进队的数据会使前进队的数据被丢掉
# q.append(1)
# q.append(2)
# q.append(3)
# print(q.popleft())
# head tail
# print(deque(open('test.txt', 'r', encoding='utf-8'), 5))
给两个字符串s和t,判断t是否为s的重新排列后组成的单词:
- ns = "anagram", t = "nagaram", return true.
- ns = "rat", t = "car", return false.
class Solution:
def isAnagram(self, s, t):
dict1 = {} # 用字典来维护字符的数量
dict2 = {}
for ch in s:
dict1[ch] = dict1.get(ch, 0) + 1 # 没有就新建,有就加1
for ch in t:
dict2[ch] = dict2.get(ch, 0) + 1
return dict1 == dict2
"""
输入:"anagram","nagaram"
输出:true
Runtime: 32 ms
"""
给定一个m*n的二维列表,查找一个数是否存在。
列表有下列特性:
- 每一行的列表从左到右已经排序好。
- 每一行第一个数比上一行最后一个数大。
- leetcode地址:https://leetcode.com/problems/search-a-2d-matrix/description/
class Solution:
def searchMatrix(self, matrix, target):
h = len(matrix) # 高
if h == 0:
return False
w = len(matrix[0]) # 列
if w == 0:
return False
left = 0
right = w * h - 1
while left <= right:
mid = ((left + right)) // 2
i = mid // w
j = mid % w
if matrix[i][j] == target:
return True
elif matrix[i][j] > target:
right = mid - 1
else:
left = mid + 1
else:
return False
给定一个列表和一个整数,设计算法找到两个数的下标,使得两个数之和为给定的整数。保证肯定仅有一个结果。
- leetcode地址:https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/
- 例如,列表[1,2,5,4]与目标整数3,1+2=3,结果为(0,1).
# [2,1,3,5] 4
# 第一种:循环 O(n^2)
def two_sum_1(li, num):
for i in range(len(li)):
for j in range(len(li)):
if i != j:
if li[i] + li[j] == num:
return i, j
return -1,-1
# 循环减半O(n^2)
def two_sum_1_1(li, num):
for i in range(len(li)):
for j in range(i+1, len(li)):
if li[i] + li[j] == num:
return i, j
def bin_search(li, val, low, high):
while low <= high: # 只要候选区不空,继续循环
mid = (low + high) // 2
if li[mid] == val:
return mid
elif li[mid] < val:
low = mid + 1
else: # li[mid] > val
high = mid - 1
return -1
# 第二种:固定一个,查找一个,查找用二分,要求有序 O(nlogn)
def two_sum_2(li, num):
for i in range(len(li)):
a = li[i]
b = num - a
j = bin_search(li, b, i+1, len(li)-1)
if j >= 0:
return i, j
# 第三种:左右互搏,要求有序 O(n)
def two_sum_3(li, num):
i = 0
j = len(li)-1
while i < j:
s = li[i] + li[j]
if s == num:
return i, j
elif s < num:
i += 1
elif s > num:
j -= 1
return -1,-1
# 第四种:用字典,字典是O(1),不要求有序 O(n)
def two_sum_4(li, num):
dic = {}
for i in range(len(li)):
a = li[i]
b = num - li[i]
if b not in dic:
dic[a] = i
else:
return dic[b], i
# 2-sum问题
# 无序列表: 4哈希表(最优)
# 有序列表: 3两边找(最优)
# 3-sum问题
# 1.暴力枚举法 O(n^3)
# 2.二分查找 O(n^2logn)
# 3.两边找 O(n^2) (最优,不占空间)
# 4.哈希表 O(n^2) (次优)
# 2-sub问题
# 哈希表 O(n) 定住一个找两个