招商银行开发岗算法题golang实现

17 篇文章 0 订阅

1、给出一个非空的字符串,判断这个字符串是否是由它的一个子串进行多次首尾拼接构成的。例如,"abcabcabc"满足条件,因为它是由"abc"首尾拼接而成的,而"abcab"则不满足条件。

思路:分为若干份,从2等分开始, 子串的最大长度为字符串的1/2,把相同的子串用空字符串替换,若替换后的字符串为空,则该字符串满足:是由子串首位拼接而成的条件。

func subString(s string) (flag bool) {
	for i := 1; i < len(s)/2+1; i++ { //分为若干份2等分开始
		sub := s[0:i]
		str := strings.ReplaceAll(s, sub, "")
		if str == "" {
			flag = true
			return
		}
	}
	return
}

2、给出一个整数n,将n分解为至少两个整数之和,使得这些整数的乘积最大化,输出能够获得的最大的乘积。

例如:2=1+1,输出1;10=3+3+4,输出36。

解题思路: //为了获取最大化的乘积,需要将n拆分更多的3,

令a=n/3;b=n%3;则n=a个3之和+b;

b分为0,1,2;

当b=0时,max=3^a;

当b=2时,max=3^a*2,若向前借一个2,变成2+3=5,5的最大乘积为3*2=6,为最大乘积,所以不变。

当b=1时,因为拆分为1,所以向前借一个3,变成3+1=4,4的最大乘积为2*2=4,若按原来为3*1=3就小了;所以max=3^(a-1)*4

再讨论n:当n<=3,max=n-1;当n>=4,按n%3=0,1,2余数分类。

func integerBreak(n int) (max float64) {
	if n == 2 {
		max = 1
	}
	if n == 3 {
		max = 2
	}
	if n > 3 {
		b := n % 3
		if b == 0 {
			max = math.Pow(float64(3), float64(n/3))
		} else if b == 1 {
			max = math.Pow(float64(3), float64(n/3-1)) * 4
		} else if b == 2 {
			max = math.Pow(float64(3), float64(n/3)) * 2
		}
	}
	return
}

3、从非负整数序列 0, 1, 2, ..., n中给出包含其中n个数的子序列,请找出未出现在该子序列中的那个数。

输入描述:

输入为n+1个非负整数,用空格分开。

其中:首个数字为非负整数序列的最大值n,后面n个数字为子序列中包含的数字。

输出描述:

输出为1个数字,即未出现在子序列中的那个数。

输入例子1:

3 3 0 1

输出 2

思路是:有的数将对应位置标志位负数-1,主要避免是0的情况, 不用处理最后的n, 如果前面没输出停止,直接输出即可;

func unpresentElem(num []int) (elem int) {
	arr := make([]int, len(num))
	for _, v := range num {
		arr[v] = -1
	}
	for index, value := range arr {
		if value != -1 && index != 0 {

			return index
		}
	}
	return
}

4、小招喵喜欢在数轴上跑来跑去,假设它现在站在点n处,它只会3种走法,分别是:

1.数轴上向前走一步,即n=n+1

2.数轴上向后走一步,即n=n-1

3.数轴上使劲跳跃到当前点的两倍,即n=2*n

现在小招喵在原点,即n=0,它想去点x处,快帮小招喵算算最快的走法需要多少步?

输入描述:     小招喵想去的位置x

输出描述:     小招喵最少需要的步数

输入例子:3            输出:3

思路-递归:设小招喵要去的位置为x,最小的步数为f(x),则f(x)满足如下关系:

1.f(0) = 0;     2.f(1) = 1;      且f(x)存在如下递推关系:

当x为偶数时,f(x) = f(x/2)+1;

当x为奇数时,f(x) = min(f((x-1)/2),f((x+1)/2))+2;

此外,还需考虑到x为负数的情况,转化为整数即可。

func minStep(x int) (steps int) {
	if x < 0 {
		x = int(math.Abs(float64(x)))
	}
	if x == 0 {
		steps = 0
	}
	if x == 1 {
		steps = 1
	} else {
		if x%2 == 0 {
			steps = minStep(x/2) + 1
		} else {
			step1 := minStep((x - 1) / 2)
			step2 := minStep((x + 1) / 2)
			steps = min(step1, step2) + 2
		}
	}
	return
}

func min(a, b int) int {
	if a <= b {
		return a
	} else {
		return b
	}
}

5、不想出差的HR:  

按照卡中心校园招聘的要求,HR小招和小商需要从三个科室中(分别为A、B、C)抽派面试官去往不同城市。
两名HR按照以下规定轮流从任一科室选择面试官:每次至少选择一位,至多选择该科室剩余面试官数。最先选不到面试官的HR需要自己出差。
假设HR小招和小商都不想出差且每次选择都采取最优策略,如果是小招先选,写一个函数来判断她是否需要出差。如果不需要出差,请给出第一步的最优策略。

输入描述:
输入为三个正整数,分别代表三个科室的面试官人数,用英文逗号分隔

输出描述:
若小招需要出差,则输出:1;
若小招不需要出差,则输出:第一步选择的科室名称和选择人数,用英文逗号分隔

输入例子1:             1,8,9

输出例子1:               1

输入例子2:              2,0,4

输出例子2:              C,2
参考:(100条消息) 不想出差的HR_ac@zhui的博客-CSDN博客

思路:典型的Nim游戏,记p = s[0]^s[1]…s[n-1],若p为0,局面为P局面,即失败;否则,我们找到与p最高位1相同的s[i],将p与s[i]异或,最终的答案ans满足p^(s[i]-ans)=0

//*  nim 游戏
func nim(nums []int) {
	room := []string{"A", "B", "C"}
	ans := 0
	for i := 0; i < len(nums); i++ {
		ans ^= nums[i]
	}

	if ans == 0 {
		fmt.Printf("%d\n", 1)
	} else {
		// 第一个先手的就是 异或后 结果小于 当前这个数的,说明没有取完
		for i := 0; i < len(nums); i++ {
			num := ans ^ nums[i]
			if nums[i]-num >= 0 {
				fmt.Printf("%s,%d\n", room[i], (nums[i] - num))
				break
			}
		}
	}
}

6、年会抢玩偶游戏

某公司年会上,组织人员安排了一个小游戏来调节气氛。游戏规则如下:N个人参与游戏,站成一排来抢工作人抛来的M个小玩偶。为了增加游戏的趣味和难度,规则规定,参与游戏的人抢到的礼物不能比左右两边的人多两个或以上,否则会受到一定的惩罚。游戏结束时拥有玩偶最多的人将获得一份大奖。
假设大家都想赢得这份大奖,请问站在第K个位置的小招在赢得游戏时,最多能拥有几个玩偶?
输入描述:
输入为用空格分隔的3个正整数,依次为:参与游戏人数N、玩偶数M、小招所在位置K
输出描述:
输出为1个正整数,代表小招最多能够拥有的玩偶数。若没有,则输出0。

2 2 2

1

算法思想:

想使得第k位的小招在不违反规则的情况下赢得游戏,那么小招与相邻参与人员的玩偶数只能依次递减1个。小招的玩偶数从最多m个依次递减,当所有人玩偶总和<=玩偶数m时,小招将获得大奖。

func dollGame(n, m, k int) (doll int) {
	//游戏人数N、玩偶数M、小招所在位置K
	if n == 0 || m == 0 || k <= 0 || k > n {
		fmt.Printf("小招拥有的玩偶数为:%d\n", 0)
		return
	} else {
		for max := m; max >= 0; max-- {
			sum := max  //小招玩偶数
			for i := 1; i <= k-1; i++ {  //小招前面k-1个人的玩偶数之和
				if max-i > 0 {
					sum += max - i
				}
			}
			for i := 1; i <= n-k; i++ {   //小招后面n-k个人的玩偶数之和
				if max-i > 0 {
					sum += max - i
				}
			}
            //小招的玩偶数从最多m个依次递减,当所有人玩偶总和<=玩偶数时,小招赢得了游戏的胜利
			if sum <= m {   
				fmt.Printf("小招拥有的玩偶数为:%d\n", max)
				return max
			}
		}
	}
	return
}

测试代码:

package main

import (
	"fmt"
	"math"
	"strings"
)

func main() {
	index := binary_search(3, []int{1, 2, 3, 4, 5, 6, 7, 8, 9})
	fmt.Println("Hello World!", index)
	s1 := "abaaba"
	s2 := "abcabcabc"
	s3 := "babb"
	flag1 := subString(s1)
	flag2 := subString(s2)
	flag3 := subString(s3)
	fmt.Println("flag1,flag2,flag3", flag1, flag2, flag3)
	max := integerBreak(5)
	fmt.Println("max", max)
	step := minStep(3)
	fmt.Println("minimumStep", step)

	//
	number := notExistElem([]int{3, 3, 0, 1})
	fmt.Println("number", number)
	nim1 := []int{2, 0, 4}
	nim2 := []int{1, 8, 9}
	nim(nim1)
	nim(nim2)

	dollGame(2, 2, 2)
}

输出:

i 0 0 9
i 1 0 4
Hello World! 2
s, sub,str abaaba a bb
s, sub,str abaaba ab aa
s, sub,str abaaba aba 
s, sub,str abcabcabc a bcbcbc
s, sub,str abcabcabc ab ccc
s, sub,str abcabcabc abc 
s, sub,str babb b a
s, sub,str babb ba bb
flag1,flag2,flag3 true true true
max 6
minimumStep 3
arr [0 0 0 0]
number 2
C,2
1
小招拥有的玩偶数为:1
成功: 进程退出代码 0.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值