golang几道算法面试题

1. 并发100个任务,但是同一时间最多运行的10个任务

利用channel缓冲管道队列满了需要等待,其他goroutine读取消息释放特性

func init() {
	count := 10
	num := 1000
	wg := sync.WaitGroup{}

	c := make(chan struct{}, count)
	for i := 0; i < num; i++ {
		wg.Add(1)
		c <- struct{}{}
		go func(j int) {
			defer wg.Done()
			fmt.Println(j)
			<-c
			time.Sleep(time.Second * 10)
		}(i)
	}
	wg.Wait()
}

2. 青蛙跳台阶,总共5个台阶可以一次1步或者2步,跳上去有几种跳法

利用斐波那契算法

func main() {
	n := 5 // 台阶数
	ways := climbStairs(n)
	fmt.Printf("对于 %d 阶台阶,共有 %d 种上法\n", n, ways)
}

func climbStairs(n int) int {
	if n <= 1 {
		return 1
	}
	if n == 2 {
		return 2
	}
	// if n == 3 {
	// 	return 4
	// }
	return climbStairs(n-1) + climbStairs(n-2)
}

func climbStairs2(n int) int {
	if n <= 1 {
		return 1
	}

	dp := make([]int, n+1)
	dp[0] = 1
	dp[1] = 1

	for i := 2; i <= n; i++ {
		dp[i] = dp[i-1] + dp[i-2]
	}
	fmt.Println(dp)
	return dp[n]
}

3. 给出一个数字在map数组中找到最相近的数字

// 给出一个数字在map数组中找到最相近的数字
func solution(ranks map[int]int, ho int) int {
	ranks[1] = 93
	ranks[10] = 55
	ranks[15] = 30
	ranks[20] = 19
	ranks[23] = 11
	ranks[30] = 2

	gap := 0
	prevGap := 0
	result := 0

	for rank, honor := range ranks {
		gap = int(math.Abs(float64(honor - ho)))
		if gap <= prevGap {
			result = rank
		}
		prevGap = gap
	}
	return result
}

4. 输入4个数字和一个期望值,通过加减乘除,算出期望值

算法有优化的地方欢迎讨论

package main

import (
	"fmt"
	"strconv"
	"strings"
)

// 用golang写一个方法,输入4个数字和一个期望值,通过加减乘除,算出期望值
func main() {
	input := []int{2, 2, 5, 4}
	target := 24
	calculate(input, target)
}

func calculate(input []int, target int) (bool, string) {
	// 定义运算符组合
	operators := []string{"+", "-", "*", "/"}
	num1, num2, num3, num4 := input[0], input[1], input[2], input[3]
	// 遍历所有可能的运算符组合
	for _, op1 := range operators {
		for _, op2 := range operators {
			for _, op3 := range operators {
				// 构建表达式
				expression := fmt.Sprintf("%d %s %d %s %d %s %d", num1, op1, num2, op2, num3, op3, num4)
				// 计算表达式结果
				result := eval(expression)
				// 判断计算结果是否等于期望值
				if result == float64(target) {
					fmt.Println(expression, "=", target)
					return true, expression
				}
			}
		}
	}

	return false, ""
}

func eval(expression string) float64 {
	// 将表达式字符串按空格分隔成切片
	tokens := strings.Split(expression, " ")
	// 优化:先计算乘法和除法
	for i := 1; i < len(tokens); i += 2 {
		operator := tokens[i]
		if operator == "*" || operator == "/" {
			operand1, _ := strconv.ParseFloat(tokens[i-1], 64)
			operand2, _ := strconv.ParseFloat(tokens[i+1], 64)
			var result float64
			switch operator {
			case "*":
				result = operand1 * operand2
			case "/":
				if operand2 == 0 {
					return 0
				}
				result = operand1 / operand2
			}
			// 替换乘法和除法的部分为计算结果
			tokens[i-1] = strconv.FormatFloat(result, 'f', -1, 64)
			// 移除乘法和除法的部分
			tokens = append(tokens[:i], tokens[i+2:]...)
			i -= 2 // 调整索引,继续循环
		}
	}

	// 初始化结果为第一个数字
	result, err := strconv.ParseFloat(tokens[0], 64)
	if err != nil {
		return 0
	}

	// 遍历剩余的运算符和数字,依次计算表达式
	for i := 1; i < len(tokens); i += 2 {
		operator := tokens[i]
		operand, err := strconv.ParseFloat(tokens[i+1], 64)
		if err != nil {
			return 0
		}
		// 根据运算符进行相应的计算
		switch operator {
		case "+":
			result += operand
		case "-":
			result -= operand
		}
	}

	fmt.Printf("%s ====> %#v ====> %f \r\n", expression, tokens, result)
	return result
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值