腾讯音乐 笔试 09.26 AC
第一题
// 字符串中只包含0和1,一次操作可以将相邻的两个字符变成'00'或'11' // 问,需要最少多少次操作将字符串全变成0或者全变成1.
public int minOperations (String str) { char cs[] = str.toCharArray(); return Math.min(fun(cs, '1'), fun(cs, '0')); } public int fun(char cs[], char target){ int ret = 0; for(int i = 0; i < cs.length; i++){ if(cs[i] == target){ ret ++; i++; } } return ret; }
第二题
// 一个数组,问有多少个连续的子数组,使得其所有元素乘积后面0的个数大于等于x // 数组长度 10**5 // [5, 2, 3, 50, 4] , 2 // [5, 2, 3, 50] [5, 2, 3, 50, 4] [2, 3, 50, 4] [2, 3, 50] [3, 50, 4] [50, 4] 共 6 种 // 暴力 // 找每个位置2、5个数,这个肯定都能想到 // 然后查看 [i-j] 区间中 2、5 的个数 // 优化 // 前缀和 + 二分查找 (下面的代码) // 再优化 // 评论区大佬提出使用滑窗的思路,直接 O(n) ,代码略
static int arr[][]; static int n; public static int getSubarrayNum (ArrayList<Integer> a, int x) { n = a.size(); arr = new int[n+1][2]; // 先存储每个位置 2、5 个数 for(int i = 0; i < n; i++){ int tmp = a.get(i); while(tmp % 2 == 0){ arr[i+1][0]++; tmp = tmp/2; } tmp = a.get(i); while(tmp%5 == 0){ arr[i+1][1]++; tmp = tmp / 5; } } // 计算前缀和 for(int i = 1; i <= n; i++){ arr[i][0] += arr[i-1][0]; arr[i][1] += arr[i-1][1]; } // 二分查找 long ret = 0; for(int i = 0; i <= n; i++){ int a2 = findIdx(0, x + arr[i][0]); int b2 = findIdx(1, x + arr[i][1]); // if(a2 > n || b2 > n) continue; ret += (n+1) - Math.max(a2, b2); ret = ret % 1000000007; } return (int)ret; } // 找满足 arr[][idx] >= val 的最左侧索引 public static int findIdx(int idx, int val){ int left = 1; int right = n; int ret = n+1; while(left <= right){ int mid = (left + right) >> 1; if(arr[mid][idx] < val){ left = mid + 1; }else{ right = mid-1; ret = mid; } } return ret; } public static void main(String[] args) { int arr[] = new int[]{5, 2, 3, 50, 4}; ArrayList<Integer> l = new ArrayList<>(); for(int item : arr) l.add(item); System.out.println(getSubarrayNum(l, 2)); }
第三题
// 数学 or 找规律题目 // 定义一个规则A:2*2区域内4个数据的和为偶数。 // 此时,有一个 N * M 的矩阵(2 <= n, m <= 10 ** 9),可以选择[1,x] (x为偶数) 中的可重复的数据进行填充 // 问,有多少种填写方式,使得这个矩阵每个 2*2 区域都符合规则 A。 // n = 2, m = 2, x = 2 result = 8,如下所示(二维转一维了,凑合看吧) // [1, 1, 1, 1] [1, 1, 2, 2] [1, 2, 1, 2] [1, 2, 2, 1] [2, 1, 2, 1] [2, 2, 1, 1] [2, 1, 1, 2] [2, 2, 2, 2]
public int numsOfGoodMatrix (int n, int m, int x) { long ret = 2; long a = func(2, m-1); // 上册 a = a % 1000000007; long b = func(2, n-1); // 左侧 b = b % 1000000007; ret = ret * a; ret = ret % 1000000007; ret = ret * b; ret = ret % 1000000007; // n*m 数值 long c = func(x>>1, m); c = func((int)c, n); ret = ret * c; return (int)(ret % 1000000007); } public long func(int val, int cnt){ if(cnt == 1) return val; long t = func(val, cnt>>1); t = t % 1000000007; t = t * t; t = t % 1000000007; if((cnt & 1) == 0){ return t; }else{ t = t * val; t = t % 1000000007; return t; } }
#笔试##腾讯音乐##23届秋招笔面经#题外话:今天经历了秋招的第一次 HR面/三面,竟然有点高兴。
主要是蚂蚁简历挂,阿里不知道什么原因官网没显示进度、但提示有在进行中的,华为400分至今没面试。秋招不易。