1、(JZ28)数组中出现次数超过一半的数字(数组,哈希)
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
# -*- coding:utf-8 -*-
from collections import defaultdict
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
dic = defaultdict(int)
for n in numbers:
dic[n] += 1
for k,v in dic.items():
if v > len(numbers)/2:
return k
return 0
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
num = map(str, numbers)
s = list(set(num))
for i in s:
if num.count(i)>len(numbers)/2:
return int(i)
return 0
2、(JZ51)构建乘积数组
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * ... * A[n-1],B[n-1] = A[0] * A[1] * ... * A[n-2];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
class Solution:
def multiply(self, A):
# write code here
B = []
for i in range(len(A)):
ans = 1
for j in range(len(A)):
if j != i:
ans = ans * A[j]
B.append(ans)
return B
上面时憨憨做法,极大占用内存。果然只有在c++中才能看到漂亮的做法。
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int len=A.size();
vector<int> B(len);
int temp=1;
for (int i=0; i<len; i++){
B[i] = temp;
temp *= A[i];
}
temp =1;
for (int i =len-1; i>=0; i--){
B[i] *= temp;
temp *= A[i];
}
return B;
}
};
换成python也没少???
# -*- coding:utf-8 -*-
class Solution:
def multiply(self, A):
# write code here
B = [1]*len(A)
temp = 1
for i in range(len(A)):
B[i] = temp
temp *= A[i]
temp = 1
for i in range(len(A)):
B[len(A)-i-1] *= temp
temp *= A[len(A)-i-1]
return B
【其他问题】关于python的内存问题(未仔细看):
如何优化python占用的内存:https://blog.csdn.net/ajian6/article/details/97167695
python内存管理及释放:https://blog.csdn.net/jiangjiang_jian/article/details/79140742
3、(JZ50)数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中第一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是第一个重复的数字2。没有重复的数字返回-1。
class Solution:
def duplicate(self , numbers ):
# write code here
if len(set(numbers))==len(numbers):
return -1
ans=[0]*len(numbers)
for n in numbers:
ans[n] += 1
if ans[n] > 1:
return n
return -1
class Solution:
def duplicate(self , numbers ):
# write code here
L = []
for n in numbers:
if n in L:
return n
else:
L.append(n)
return -1
class Solution:
def duplicate(self , numbers ):
# write code here
record = set()
for n in numbers:
if n in record:
return n
record.add(n)
return -1
4、(JZ42)和为S的两个数字
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
瞎胡解
# -*- coding:utf-8 -*-
import sys
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
ans = []
if not array:
return ans
dif = 0
p = 0
q = len(array)-1
while array[q]>=tsum:
q -= 1
while p<q:
ts = array[p]+array[q]
if ts==tsum and array[q]-array[p]> dif:
ans = [array[p],array[q]]
dif = array[q]-array[p]
elif ts < tsum:
p += 1
else:
p = 0
q -= 1
return ans
上面的解法else之后从0开始有点浪费
# -*- coding:utf-8 -*-
import sys
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
ans = []
if not array:
return ans
cha = 0
p = 0
q = len(array)-1
while array[q]>=tsum:
q -= 1
while p<q:
ts = array[p]+array[q]
if ts==tsum and array[q]-array[p]> cha:
ans = [array[p],array[q]]
cha = array[q]-array[p]
elif ts < tsum:
p += 1
else:
p = 0
q -= 1
return ans
5、(JZ37)数字在排序数组中出现的次数
统计一个数字在升序数组中出现的次数。
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
if k not in data:
return 0
index = data.index(k)
num = 0
for i in range(index, len(data)):
if data[i] == k:
num += 1
return num
# -*- coding:utf-8 -*-
class Solution:
def GetNumberOfK(self, data, k):
# write code here
count = 0
for i in range(len(data)):
if k == data[i]:
count += 1
return count
6、(JZ4)重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:充分利用前序遍历和中序遍历的特点。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
# write code here
if not pre or not tin:
return None
root = TreeNode(pre.pop(0))
index = tin.index(root.val)
root.left = self.reConstructBinaryTree(pre,tin[:index])
root.right = self.reConstructBinaryTree(pre,tin[index+1:])
return root
7、(JZ1)二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
# 最简单粗暴的方法
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
if not array:
return False
rows = len(array)
cols = len(array[0])
for r in range(rows):
for c in range(cols):
if array[r][c] == target:
return True
return False
思路:首先我们选择从左下角开始搜寻,(为什么不从左上角开始搜寻,左上角向右和向下都是递增,那么对于一个点,对于向右和向下会产生一个岔路;如果我们选择从左下脚开始搜寻的话,如果大于就向右,如果小于就向下)。从左下角元素往上找,右边元素大,上面元素小。若出了边界,则表示不存在target元素。
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
rows = len(array)-1
cols = len(array[0])-1
i = rows
j = 0
while j<=cols and i>=0:
if target<array[i][j]:
i -= 1
elif target>array[i][j]:
j += 1
else:
return True
return False
8、调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param array int整型一维数组
# @return int整型一维数组
#
class Solution:
def reOrderArray(self , array ):
# write code here
index = 0
ans = []
if not array:
return ans
for n in array:
if n % 2 == 1:
ans.insert(index, n)
index += 1
else:
ans.append(n)
return ans
9、斐波那契数列
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n\leq 39n≤39
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
# write code here
if n <= 1:
return n
a = 0
b = 1
for i in range(n-1):
temp = a + b
a = b
b = temp
return temp
10、顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
关键在于——边界条件选定
if matrix and matrix[0]
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# write code here
ans = []
if len(matrix)==1:
return matrix[0]
while matrix:
ans.extend(matrix.pop(0))
if matrix and matrix[0]:
for i in range(len(matrix)):
ans.append(matrix[i].pop())
if matrix and matrix[0]:
ans += matrix.pop()[::-1]
if matrix and matrix[0]:
for j in reversed((range(len(matrix)))):
ans.append(matrix[j].pop(0))
return ans
[::-1] -1表示步进
extend a = [1,2] b=[3,3] a.extend(b) # a = [1,2,3,4] 列表合并
reversed 函数返回一个反转的迭代器。
11、(JZ32)把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。(遗留问题)
# -*- coding:utf-8 -*-
class Solution:
def PrintMinNumber(self, numbers):
# write code here
n = len(numbers)
if n==0:
return ''
if n==1:
return numbers[0]
compare = lambda n1, n2: int(str(n1)+str(n2))-int(str(n2)+str(n1))
array = sorted(numbers, cmp=compare)
return ''.join([str(i) for i in array])
sorted(numbers, cmp=compare)
# -*- coding:utf-8 -*-
import itertools
class Solution:
def PrintMinNumber(self, numbers):
# write code here
ret = []
numbers = list(map(str,numbers))
mm = itertools.permutations(numbers)
for i in mm:
ret.append(''.join(i))
ret.sort()
return ret[0]
itertools.permutations(iterable, r=None) 全排列
连续返回由 iterable 元素生成长度为 r 的排列。
如:
import itertools
nums = ['a','b','c']
for num in itertools.permutations(nums, 3):
a = num[0] + num[1] + num[2]
print(a)
'''
abc
acb
bac
bca
cab
cba
'''