华为OD机试三(完全二叉树部分后续遍历、猜密码、五子棋谜)

1. 完全二叉树部分后续遍历

题目表述:

在这里插入图片描述
输入: 1 2 3 4 5 6 7
输出: 2 3 1

示例代码:

# 测试数据
test_data = [1,2,3,4,5,6,7]
# 找出非叶子节点
new_list = []
for i in test_data:
	left = 2 * i
	right = left + 1
	if left in test_data or right in test_data:
		new_list.append(i)
# 遍历二叉树
# 根元素
cur_ele = 1
res = []

def tree(root,ele_list):
	# 后续遍历: 左 -> 右 -> 根
	left = root * 2
	if left in ele_list:
		tree(left,ele_list)
	right = left + 1
	if right in ele_list:
		tree(right,ele_list)
	res.append(root)

tree(cur_ele,new_list)
print(res)

2. 猜密码

题目描述:
小杨申请了一个保密柜,但是他忘记了密码。只记得密码都是数字,
而且所有数字都是不重复的。请你根据他记住的数字范围和密码的最
小数字数量,帮他算下有哪些可能的组合,规则如下:
1、输出的组合都是从可选的数字范围中选取的,且不能重复;
2、输出的密码数字要按照从小到大的顺序排列,密码组合需要按照
字母顺序,从小到大的顺序排序。
3、输出的每一个组合的数字的数量要大于等于密码最小数字数量;
4、如果可能的组合为空,则返回“None”
示例:
输入:2,3,4
		   2
输出:2,3
     2,3,4
	 2,4
	 3,4

算法参考下图:
在这里插入图片描述

示例代码:

# 测试数据
test_data = [2,3,4,5]
test_num = 2

def fun(s_list,num):
	# 密码长度为1
	if num == 1:
		for _ in s_list:
			tmp = []
			tmp.append(_)
			print(tmp)
	# 密码长度大于2
	start = 0
	while start < len(s_list) - 1:
		end = start + (num - 2)
		while end < len(s_list) - 1:
			last = end + 1
			while last < len(s_list):
				tmp = s_list[start:end+1]
				tmp.append(s_list[last])
				print(tmp)
				last += 1
			end += 1
		start += 1
fun(test_data,test_num)

3. 五子棋谜

题目描述:
张兵和王武是五子棋迷,工作之余经常切磋棋艺。这不,这会儿又下
起来了。走了一会儿,轮张兵了,对着一条线思考起来了,这条线上
的棋子分布如下:
用数组表示: -1 0 1 1 1 0 1 0 1 -1
棋子分布说明:
	1. -1代表白子,0代表空位,1 代表黑子
	2. 数组长度L, 满足 1 < L < 40, 且L为奇数
你得帮他写一个程序,算出最有利的出子位置。 最有利定义:
	1. 找到一个空位(0),用棋子(1/-1)填充该位置,可以使得当前子的
	   最大连续长度变大;
	2. 如果存在多个位置,返回最靠近中间的较小的那个坐标;
	3.  如果不存在可行位置,直接返回-1;
	4. 连续长度不能超过5个(五字棋约束);
示例:
输入:1
     -1 0 1 1 1 0 1 0 1 -1 1
输出:2

算法参考下图:
在这里插入图片描述

示例代码:

from math import fabs

def fun(s_list,ele):
	
	start = 0
	end = len(s_list) - 1
	pos = start

	pos_list = []
	cur_pos = -1
	while pos <= end:
		if s_list[pos] == 0:
			left = pos
			right = pos
			while right - left <= 4 and left >= start and right <= end:
				before_left = left
				before_right = right
				if left != 0 and s_list[left - 1] == ele:
					left -= 1
				if right != end and s_list[right + 1] == ele:
					right += 1
				if left == before_left and right == before_right:
					break;
			if right - left >= cur_long and right != left:
				cur_pos = pos
				cur_long = right - left
				pos_list.append(cur_pos)
		pos += 1
	
	if cur_pos == -1:
		return cur_pos
	else:
		middle_pos = pos_list[0]
		middle_length = len(s_list) / 2
		for pos in pos_list:
			if fabs(pos - middle_length) <= fabs(middle_pos - middle_length):
				middle_pos = pos
		return middle_pos
test_data = [-1, 0, 1, 1, 1, 0, 1, 0, 1, -1, 1]
fun(test_data,1)
  • 26
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值