2020.3.27 阿里笔试题目

  1. 给定两个等长字符串,长度范围1e5,你可以选择第一个字符串的一个字符移动到字符串尾部,目的是让两个字符串相等,求最小的移动次数

思路: 问题可以转换为第一个字符串的子序列长度等于第二个字符串的前缀的最大匹配长度,最小移动次数是字符串长度-公共子序列长度; 如果字符数量不匹配,则为false

import collections


class Solution:
    def solu(self, s1, s2):
        # 最大公共序列的长度
        max_len = 0
        # 如果字符数量不匹配,则为false
        s1_count = collections.Counter(s1)
        s2_count = collections.Counter(s2)
        for key, value in s1_count.items():
            if s1_count[key] != s2_count[key]:
                return -1
        # 求最大公共子序列长度
        for i in range(len(s1)):
            # 临时最大公共序列长度
            count = 0
            # 字符串2的当前遍历位置
            start = 0
            for j in range(i, len(s1)):
                # 如果遍历位置相等,则长度+1,继续往后遍历
                if s1[j] == s2[start]:
                    count += 1
                    start += 1
                # 如果不想等则break
                elif s1[j] != s2[start]:
                    break
                # 如果当前长度大于最大长度,则更新值
                if count > max_len:
                    max_len = count
        return len(s1) - max_len


if __name__ == '__main__':
    s = Solution()
    l = list(input().strip().split())
    s1, s2 = l[0], l[1]
    result = s.solu(s1, s2)
    print(result)
  1. 给定n(n <= 2000)个区间[L,R](1 <= L <= R <= 2000),从这n个区间中分别等概率取一个整数,一共n个数,求这些数最小值的期望。

注: 看不懂啥意思,先贴上别人的思路代码…
网上思路:
首先最小值最小为l的最小值,最大为r的最小值,分别表示为min1和min2,所以只要对min1和min2之间的数计算概率即可。
x作为最小值的概率=选择的所有数大于等于x的概率-选择的所有数大于等于x+1的概率
所以两层循环,外层为min1-min2,表示最小值的选择,
内层为0-n,表示对每个数组选择一个数,选择的数大于等于x的概率,遍历一遍,找到所有数大于x的概率,保存数组。
x作为最小值的概率 = p(x)-p(x+1)

作者:〢ヽ夜╰︶ ̄太美
链接:https://www.nowcoder.com/discuss/393218?type=1
来源:牛客网

#include
using namespace std;
const int N = 2e3 + 7;
int L[N], R[N];
double p[N];
int main() {
	int n; scanf("%d", &n);
	for(int i = 0; i < n; i++)scanf("%d", &L[i]);
	for(int i = 0; i < n; i++)scanf("%d", &R[i]);
	p[1] = 1;
	for(int i = 2; i <= 2000; i++) {
		double sum = 1;
		for(int j = 0; j < n; j++) {
			if(i <= L[j]);
			else if(i > R[j])sum = 0;
			else sum *= 1.0 * (R[j] - i + 1) / (R[j] - L[j] + 1);
		}
		p[i] = sum;
	}
	double ans = 0;
	for(int i = 1; i <= 2000; i++)ans += i * (p[i] - p[i + 1]);
	printf("%.10lf\n", ans);
}

你可能感兴趣的:(算法笔试真题,阿里笔试真题)