每日算法&面试题,大厂特训二十八天——第十三天(数组)

452 阅读4分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

导读

在这里插入图片描述

肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!!

算法特训二十八天

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

思路:由于同一个数字在两个数组中都可能出现多次,因此需要用哈希表存储每个数字出现的次数。对于一个数字,其在交集中出现的次数等于该数字在两个数组中出现次数的最小值。

首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,则将该数字添加到答案,并减少哈希表中该数字出现的次数。

为了降低空间复杂度,首先遍历较短的数组并在哈希表中记录每个数字以及对应出现的次数,然后遍历较长的数组得到交集。

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return intersect(nums2, nums1);
        }
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num : nums1) {
            int count = map.getOrDefault(num, 0) + 1;
            map.put(num, count);
        }
        int[] intersection = new int[nums1.length];
        int index = 0;
        for (int num : nums2) {
            int count = map.getOrDefault(num, 0);
            if (count > 0) {
                intersection[index++] = num;
                count--;
                if (count > 0) {
                    map.put(num, count);
                } else {
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
}


在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

在这里插入图片描述

示例 1:


输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]

在这里插入图片描述

示例 2:


输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]
class Solution {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int m = nums.length;
        int n = nums[0].length;
        if (m * n != r * c) {
            return nums;
        }

        int[][] ans = new int[r][c];
        for (int x = 0; x < m * n; ++x) {
            ans[x / c][x % c] = nums[x / n][x % n];
        }
        return ans;
    }
}

面试题

undo log 具体怎么回滚事务 ?
举个例子:
 对于 insert 类型的 sql,会在 undo log 中记录下方才你 insert 进来的数据的 ID,当你
想 roll back 时,根据 ID 完成精准的删除。
 对于 delete 类型的 sql,会在 undo log 中记录方才你删除的数据,当你回滚时会将删
除前的数据 insert 进去。
 对于 update 类型的 sql,会在 undo log 中记录下修改前的数据,回滚时只需要反向
update 即可。
 对于 select 类型的 sql,别费心了,select 不需要回滚。


如何查询慢 SQL 产生的原因?
 分析 SQL 执行计划(explain extended),思考可能的优化点,是否命中索引等。
 没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)。
 内存不足。
 网络速度慢。
 是否查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。
 是否返回了不必要的行和列。
 锁或者死锁。
 I/O 吞吐量小,形成了瓶颈效应。
 sp_lock,sp_who,活动的用户查看,原因是读写竞争资源