剑指offer刷题
1、在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
输入:7,
[[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]]
输出:7
讲解:讲解
答案:
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
def Find(self, target, array):
rows = len(array)
cols = len(array[0])
if rows > 0 and cols > 0:
row = 0
col = cols - 1
while row < rows and col>=0 :
if target == array[row][col]:
return True
elif target < array[row][col]:
col = col - 1
else :
row = row + 1
return False
# write code here
2、请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
输入:“We Are Happy”
输出:“We%20Are%20Happy”
讲解:讲解
知识点:Python replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
str.replace(old, new[, max])
class Solution:
def replaceSpace(self , s ):
return s.replace(' ','%20')
# write code herere
3、在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
输入:“google”
输出:l
知识点 :字符串的基础知识:字符串
count():计算字符串中的出现某个字符的次数
class Solution:
def FirstNotRepeatingChar(self, s):
if len(s)<=0 or len(s)>10000:
return -1
else:
for i in s :
if s.count(i)==1 :
return s.index(i)
break
遍历字符串中的每一个字母,使用count 方法==1 ,就break退出循环
找到第一个出现一次的字符就break 结束循环
4、大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。n≤39
讲解:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2),就是求f(n)的值是多少
可使用递归 可使用 简单的循环
简单循环:
def Fibonacci(self, n):
if n == 0:
return 0
a = 0
b = 1
for i in range(1,n) :
a , b = b, a+b #不可以写成a = b b = a + b
return b
递归:这种方法显示 运行时间过长或者是空间占用量太大了
def Fibonacci(self, n):
if n == 0 :
return 0
elif n == 1 :
return 1
else :
return self.Fibonacci(n-1) + self.Fibonacci(n-2)
5、输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
输入:[1,2,3,4]
输出:[1,3,2,4]
讲解:建两个数组 初始化 qian = [] hou = []
然后把两个拼接起来qian + hou
def reOrderArray(self , array ):
qian = []
hou = []
for i in array :
if i%2 == 1 :
qian.append(i)
else:
hou.append(i)
return qian+hou
5、数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
输入:[1,2,3,2,2,2,5,4,2]
输出:2
分析 找出出现次数大于总长度一般的即可 一开始设置一个标志 如果找到了改变标志 找不到标志不变再判断一下标志 看是否返回0
def MoreThanHalfNum_Solution(self, numbers):
a = len(numbers)/2
count = 0
for i in numbers:
if numbers.count(i)>a:
count = 1
return i
if count == 0 :
return 0
6、汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
输入:“abcXYZdef”,3
输出:“XYZdefabc”
def LeftRotateString(self, s, n):
s1 = s[:n]
s2 = s[n:]
return s2+s1
7、牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
输入:“nowcoder. a am I”
输出:“I am a nowcoder.”
def ReverseSentence(self, s):
s = s.split(' ')
s.reverse()
return ' '.join(s)
8、一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
输入:[1,4,1,6]
输出:[4,6]
def FindNumsAppearOnce(self , array ):
num_count = {}
result = []
for i in array :
num_count[i] = num_count.get(i,0) + 1
for key,value in num_count.items():
if value == 1:
result.append(key)
return result
9、输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
讲解:讲解
def NumberOf1(self, n):
count = 0
if n<0 :
n = n & 0xffffffff
while n:
count = count +1
n = n&(n-1)
return count
10、给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
输入:2 3
输出:8.0000
考虑到 指数为负的时候 取倒数 考虑 base不可以为0
def Power(self, base, exponent):
if base == 0 and exponent ==0 :
return False
if base == 0:
return False
flag = 0
result = 1
if exponent< 0 :
flag = 1
for i in range(abs(exponent)):
result*=base
if flag == 1:
result = 1/result
return result
47、求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
输入:5
输出:15`
`def Sum_Solution(self, n):
return sum(range(1,n+1)
48、写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号
输入:1 2
输出:3
讲解:
1、先将各bit位相加,不计进位,这一步可以用m^n实现
2、加上进位,进位如何来,用m&n可以得到m和n中都为1的bit位,而不全为1的位则全部变为了0,该位相加会发生进位,使得左边一位加1,因此(m&n)<<1边可得到进位后要加的1的位置;
3、将前面两步的结果相加,相加的时候还有可能再产生进位,因此二者相加的过程可以再次重复循环步骤1和2,直到(m&n)<<1变为了0,这时候不会再产生进位,退出循环即可。
def Add(self, num1, num2):
while num2 != 0:
sum1 = num1^num2
add1 = (num1&num2)<<1
num1 = sum1&0xffffffff
num2 = add1
return num1 if num1 >> 31 == 0 else num1 - 4294967296
3、输入一个链表,按链表从尾到头的顺序返回一个ArrayList
输入:{67,0,24,58}
输出:[58,24,0,67]
讲解:讲解
def printListFromTailToHead(self, listNode):
result = []
if listNode is None:
return result
while listNode.next is not None:
result.append(listNode.val)
listNode = listNode.next
result.extend([listNode.val])
return result[::-1]
def printListFromTailToHead(self, listNode):
result = []
while listNode:
result.insert(0,listNode.val)
listNode = listNode.next
return result
6、把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
讲解讲解
def minNumberInRotateArray(self, rotateArray):
return min(rotateArray)
def minNumberInRotateArray(self, rotateArray):
for i in range(len(rotateArray)):
if rotateArray[i+1] <rotateArray[i]:
return rotateArray[i+1]
return 0
def minNumberInRotateArray(self, rotateArray):
if not rotateArray:
return 0
if len(rotateArray) == 2 :
return rotateArray[1]
mid = int(len(rotateArray)/2)
if rotateArray[mid] > rotateArray[0]:
return self.minNumberInRotateArray(rotateArray[mid:])
elif rotateArray[mid] <rotateArray[0]:
return self.minNumberInRotateArray(rotateArray[:mid+1])
else:
for i in range(1,len(rotateArray)):
if rotateArray[i]<rotateArray[0]:
return rotateArray[i]
return rotateArray[0]
8、一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
输入;4
输出:5
def jumpFloor(self, number):
if number == 1:
return 1
a = 0
b = 1
for i in range(number):
a,b = b,a+b
return b
9、一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
讲解
def jumpFloorII(self, number):
return 2**(number-1)
10、我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
比如n=3时,2*3的矩形块有3种覆盖方法:
讲解
def rectCover(self, number):
if number == 0:
return 0
a = 0
b = 1
for i in range(number):
a,b = b,a+b
return b
14、输入一个链表,输出该链表中倒数第k个结点。
讲解111
def FindKthToTail(self , pHead , k ):
if pHead == None or k <=0:
return None
p1 = pHead
p2 = pHead
while k >1:
if p2.next != None :
p2 = p2.next
k-=1
else:
return None
while p2.next!=None:
p1=p1.next
p2=p2.next
return p1
5、用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
讲解
class Solution:
def __init__(self):
self.stack1 = []
self.stack2 = []
def push(self, node):
# write code here
self.stack1.append(node)
def pop(self):
if self.stack2:
return self.stack2.pop()
else:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()