8月28日 阿里笔试 研发工程师C/C++

本文分享了8月28日阿里笔试中研发工程师C/C++岗位的两道题目。第一题讨论如何从字符串A转换到字符串B的最小步骤,分析了不同操作的影响。第二题涉及全排列问题,通过Go语言的特性解释了解题思路,并提到C++的next_permutation函数在解决全排列问题上的高效应用。

8月28日 阿里笔试

第1题

如果对于一个 01 字符串,每次可以进行如下操作中的一种。

  • 只能交换任意两个元素
  • 把一个0变成1或把一个1变成0
  • 翻转整个字符串

请问从A串变成B串最少需要多少步?

我们先分析一波。

在这里插入图片描述
我们要用三种操作将字符串 origin 变成 target
尽管不一定最优,假设我们得到了一种可行方案。
假设这个方案里的翻转次数 r>1,那么我们一定可以消除其中的两次翻转操作达到一样的效果。
现在我们的方案里只有0次或1次翻转操作。假设现在我们的方案里仍然有1次翻转操作,那么翻转操作一定可以挪到最开始首先进行。那么我们得到翻转字符串 reversed
那么就得到两种可能的方案。
第一种:将字符串 origin 进行 交换改变 得到 target
第二种:将字符串 origin 翻转 得到 reversed, 再对 reversed 进行 交换改变 得到 target

我无法判断在这两种情况中哪一种转化为 target 所需要的步数更少。因此我们对字符串 originreversed 都进行受限的转换(交换改变)得到 target,并比较总步数取较小值。

接下来我们继续考虑用受限的转换将字符串 origin 变成 target
交换一次消一对,改变一次消一个。
交换的时候我们无脑交换就行了。

origintarget不匹配有两种情况:

  • dismatch0: origin[i]=='1' && target[i]=='0'
  • dismatch1: origin[i]=='0' && target[i]=='1'

如果两类不匹配分别有 dismatch0dismatch1 个。
那么我们可以用交换消除 min(dismatch0,dismatch1),剩余的不匹配用改变逐一处理。
交换改变的次数之和为 max(dismatch0,dismatch1)

package main

import "fmt"

func convert(origin,target string) (n int) {
   
   
	k:=0
	for i:=0;i< len(origin);i++{
   
   
		if origin[i]!=target[i]{
   
   
			k++
		}
	}
	reversed:=""
	for _,v:=range origin{
   
   
		reversed=string(v)+reversed
	}
	return min(1+convertBanRev(reversed,target),convertBanRev(origin,target))
}

func convertBanRev(origin,target string) (n int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值