解题思路:从头到尾遍历一次,如果碰到偶数,则从该偶数位置往后查找,查找到第一个奇数,将该奇数值记录下来,pop掉之后,再将该奇数插入到偶数之前的位置;
class Solution:
def reOrderArray(self, array):
# write code here
left = 0
n = len(array)
while left < n:
if array[left]%2!=0:
left += 1
else:
for i in range(left+1,n):
if array[i]%2!=0:
tmp = array[i]
array.insert(left,tmp)
array.pop(i+1)
break
left += 1
return array
2.镜像二叉树:
class Solution:
# 返回镜像树的根节点
def Mirror(self, root):
# write code here
if not root:
return root
node = root.left
root.left = root.right
root.right = node
self.Mirror(root.left)
self.Mirror(root.right)
return root
3.输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
解题思路:二叉搜索树有一个性质,根节点的值要大于左子树所有值,小于右子树所有值。因为后序遍历最后一个值为子树的根结点,那么先得到数组最后一个值a,然后再找到第一个比a大的数,在a之前的为左子树,在a之后的为右子树,再观察右子树中是否所有值都大于a,如果不满足则return False。递归
代码:
class Solution:
def VerifySquenceOfBST(self, sequence):
# write code here
s = sequence
if s == None or len(s) == 0:
return False
n = len(s)
root = s[n-1]
for i in range(n):
if s[i] > root:
break
for j in range(i,n):
if s[j] < root:
return False
left = True
if i > 0:
left = self.VerifySquenceOfBST(s[0:i])
right = True
if i < n-1:
right = self.VerifySquenceOfBST(s[i:n-1])
return left and right
4.输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
解题思路:递归,回溯,找到所有组合
# -*- coding:utf-8 -*-
class Solution:
def dfs(self,res,n,ss,temp,book):
if len(temp) == n and temp not in res:
res += [temp]
return
for i in range(n):
if book[i] == 0:
book[i] = 1
self.dfs(res,n,ss,temp+ss[i],book)
book[i] = 0
def Permutation(self, ss):
# write code here
res = []
n = len(ss)
if n == 0 or n==1:
return ss
book = [0]*n
self.dfs(res,n,ss,'',book)
return res
5.输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
思路:创建两个指针,一个指向头一个指向尾。res只记录满足两数之和等于tsum的并且乘机和(muti)当前最小的两个数。
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
low = 0
high = len(array)-1
res = []
muti = 10000
while low
6.汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思路:创建一个旋转函数(逆序函数),如’abc’→’cba’,然后对字符串按k分成两块,分别调用旋转函数,再对整体调用一次旋转函数。涉及字符串换位旋转的都可以用这种方法。
# -*- coding:utf-8 -*-
class Solution:
def change(self,s):
return s[::-1]
def LeftRotateString(self, s, n):
# write code here
s1 = self.change(s[0:n])
s2 = self.change(s[n:])
res = self.change(s1+s2)
return res
7.例如,“student. a am I”。这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路:与上题类似,对每个单词旋转,再对整体旋转,注意空格
# -*- coding:utf-8 -*-
class Solution:
def change(self,s):
return s[::-1]
def ReverseSentence(self, s):
# write code here
s = s.split(' ')
s_reverse = ''
for x in s:
s_reverse += self.change(x) + ' ' #结尾会多个空格
return self.change(s_reverse)[1:] #结尾的空格反转到了头部,所以从1位置之后打印
8.上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
思路:排序后,统计0的个数,如果0的个数>=4,则直接返回True,否则,遍历一次剔除0的数组,前后差距如果==1,则continue;如果 != 1 ,那么在该i位置插入numbers[i-1]+1的值,并使num_0-1,如果当num_0等于一的时候还出现前后差距>1的情况,直接返回False。
# -*- coding:utf-8 -*-
class Solution:
def IsContinuous(self, numbers):
# write code here
if not numbers:
return False
numbers = sorted(numbers)
n = len(numbers)
num_0 = numbers.count(0)
numbers = numbers[num_0:]
if num_0 >= 4:
return True
for i in range(1,n):
if numbers[i] - numbers[i-1] != 1 and num_0 == 0:
return False
elif numbers[i] - numbers[i-1] != 1 and num_0 != 0:
numbers.insert(i,numbers[i-1]+1)
num_0 -= 1
return True
9.一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
思路:hash,遍历一遍存入字典,然后对字典value值升序排序,取出前两个。
# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
# write code here
# res = []
# for x in array:
# if array.count(x) == 1:
# res.append(str(x))
# return res
dic = {}
for i in range(len(array)):
if array[i] not in dic.keys():
dic[array[i]] = 1
else:
dic[array[i]] += 1
dic = sorted(dic.items(),key = lambda x:x[1],reverse = False)
return [dic[0][0],dic[1][0]]
对于一个有序数组arr,再给定一个整数num,请在arr中找到num这个数出现的最左边的位置。
给定一个数组arr及它的大小n,同时给定num。请返回所求位置。若该元素在数组中未出现,请返回-1。
测试样例:
[1,2,3,3,4],5,3
返回:2
# -*- coding:utf-8 -*-
class LeftMostAppearance:
def findPos(self, arr, n, num):
# write code here
res = -1
left, right = 0, n-1
while left <= right:
mid = left+(right-left)/2
if arr[mid] > num:
right = mid - 1
continue
if arr[mid] < num:
left = mid + 1
continue
if arr[mid] == num:
res = mid
right = mid - 1
return res
对于一个有序循环数组arr,返回arr中的最小值。有序循环数组是指,有序数组左边任意长度的部分放到右边去,右边的部分拿到左边来。比如数组[1,2,3,3,4],是有序循环数组,[4,1,2,3,3]也是。
给定数组arr及它的大小n,请返回最小值。
测试样例:
[4,1,2,3,3],5
返回:1
# -*- coding:utf-8 -*-
class MinValue:
def getMin(self, arr, n):
low=0
high=n-1
# arr[low] >= arr[high]
while low<=high:#和寻找元素最左出现的位置”这部分是一样的
mid=low+(high-low)/2
if arr[low]>arr[mid]: #左一半
high=mid
elif arr[mid]>arr[high]: #右一半
low=mid+1
else: #arr[low]==arr[mid]==arr[right] 特殊情况 只能挨个遍历,之前两个if最后到了一个元素的也会到达这里进行最终的判断
cur=arr[low]
while low arr[low+1]:
cur=arr[low+1]
low=low+1
return cur
12.动态规划割绳子:
给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],…,k[m].请问k[0]k[1]…*k[m]可能的最大乘积是多少?
例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积是18.
def cut(n):
if n==1:
return 0
if n==2:
return 1
if n==3:
return 2
dp = [0]*(n+1)
dp[0] = 0
dp[1] = 1
dp[2] = 2
dp[3] = 3
for i in range(4,n+1):
max0 = -1
for j in range(1,i//2+1):
p = dp[j]*dp[i-j]
if max0