提交 b9b91bad 编写于 作者: C chenguangjian.jk

csdn exercises

上级 a465ea71
# 机器猫
小光买了一个可编程机器猫,机器猫初始位置在原点(0, 0)。
小伙伴事先给机器猫输入一串指令command,机器猫就会无限循环这条指令的步骤进行移动。指令有两种:
U: 向y轴正方向移动一格
R: 向x轴正方向移动一格。
不幸的是,在 xy 平面上还有一些障碍物,他们的坐标用obstacles表示。机器猫一旦碰到障碍物就会被损毁。
限制:
2 <= command的长度 <= 1000
command由 U,R 构成,且至少有一个 U,至少有一个 R
0 <= x <= 1e9, 0 <= y <= 1e9
0 <= obstacles 的长度 <= 1000
obstacles[i]不为原点或者终点
## 输入描述
一串UR指令: command
障碍物坐标数组: obstacles
终点坐标(x, y)
## 输出描述
返回机器猫能否完好地到达终点。如果能,返回true;否则返回false。
# 示例
## 示例 1:
输入:command = "URR", obstacles = [], x = 3, y = 2
输出:true
解释:U(0, 1) -> R(1, 1) -> R(2, 1) -> U(2, 2) -> R(3, 2)。
## 示例 2:
输入:command = "URR", obstacles = [[2, 2]], x = 3, y = 2
输出:false
解释:机器猫在到达终点前会碰到(2, 2)的障碍物。
## 示例 3:
输入:command = "URR", obstacles = [[4, 2]], x = 3, y = 2
输出:true
解释:到达终点后,再碰到障碍物也不影响返回结果。
# 提示
无.
class Solution {
public boolean robot(String command, int[][] obstacles, int x, int y) {
int dx = 0, dy = 0;
char[] cmd = command.toCharArray(); // 把String转为数组,方便遍历。
for (char c : cmd) { // 算出up和right各有多少个。
if (c == 'U') dy++;
else dx++;
}
int ans = isPassed(cmd, x, y, dx, dy); // 拿到走到终点的次数。
/*
为什么isPassed要拿到走的总次数而不直接返回true或false呢
比如你发现有一个obstacle是经过的,那么最终答案并不一定是false,
因为如果终点在这个点的前面,那么机器人根本不会走到那个点。答案是true。
*/
if (ans == -1) return false; // 终点都没经过,肯定false
for (int[] obstacle : obstacles) {
int cnt = isPassed(cmd, obstacle[0], obstacle[1], dx, dy);
if (cnt != -1 && cnt < ans) return false;
//不等于-1,说明经过了,然后再看这个点和终点哪个次数多。ans多,说明这个点在ans前面,返回false。
}
return true;
}
// 判断是否经过该点,经过返回走的次数,没经过返回-1。
public int isPassed(char[] cmd, int x, int y, int dx, int dy) {
int round = Math.min(x / dx, y / dy); // 计算走到第x-1或y-1层需要多少轮
int cnt = cmd.length * round; // 前几轮的总次数
dx *= round;
dy *= round; // 在第x-1或y-1层时的位置。
if (dx == x && dy == y) return cnt; // 正好就是要找的点,直接返回。
for (char c : cmd) { // 遍历第x层或y层,如果经过,那么答案一定会遍历到。
if (c == 'U') dy++; // 要按command的顺序走
else dx++;
cnt++; // 不要忘了每遍历一次,次数都要加1
if (dx == x && dy == y) return cnt; // 一旦找到,直接返回所需要的次数。
}
return -1;
}
}
URR
[[2, 2]]
3
2
\ No newline at end of file
URR
[[4, 2]]
3
2
\ No newline at end of file
UUR
[[4, 2], [3, 3]]
5
9
\ No newline at end of file
RRU
[[1, 2], [5, 3]]
9
6
\ No newline at end of file
RURU
[[5, 3]]
6
6
\ No newline at end of file
RUR
[[1, 2]]
3
7
\ No newline at end of file
URU
[[3, 4]]
10
10
\ No newline at end of file
RURRU
[[2, 2]]
30
20
\ No newline at end of file
# 求解秩矩阵
给你一个 m x n 的矩阵 matrix ,请你返回一个新的矩阵 answer ,其中 answer[row][col] 是 matrix[row][col] 的秩。
这里定义的每个元素的 秩 是一个整数,表示这个元素相对于其他元素的大小关系,它按照如下规则计算:
(1)秩是从 1 开始的一个整数。
(2)如果两个元素 p 和 q 在 同一行 或者 同一列 ,那么:
如果 p < q ,那么 rank(p) < rank(q)
如果 p == q ,那么 rank(p) == rank(q)
如果 p > q ,那么 rank(p) > rank(q)
秩 需要越 小 越好。
题目保证按照上面规则 answer 数组是唯一的。
参数说明:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 500
-10^9 <= matrix[row][col] <= 10^9
# 示例
## 输入样例1
[[1,2],[3,4]]
## 输出样例1
[[1,2],[2,3]]
## 输入样例2
[[7,7],[7,7]]
## 输出样例2
[[1,1],[1,1]]
## 输入样例3
[[20,-21,14],[-19,4,19],[22,-47,24],[-19,4,19]]
## 输出样例3
[[4,2,3],[1,3,4],[5,1,6],[1,3,4]]
# 提示
输出样例1的解释说明:
matrix[0][0] 的秩为 1 ,因为它是所在行和列的最小整数。
matrix[0][1] 的秩为 2 ,因为 matrix[0][1] > matrix[0][0] 且 matrix[0][0] 的秩为 1 。
matrix[1][0] 的秩为 2 ,因为 matrix[1][0] > matrix[0][0] 且 matrix[0][0] 的秩为 1 。
matrix[1][1] 的秩为 3 ,因为 matrix[1][1] > matrix[0][1], matrix[1][1] > matrix[1][0] 且 matrix[0][1] 和 matrix[1][0] 的秩都为 2 。
class Solution {
public int[][] matrixRankTransform(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
UnionFind uf = new UnionFind(m, n);
for (int i = 0; i < m; i++) {
Map<Integer, List<int[]>> num2indexList = new HashMap<Integer, List<int[]>>();
for (int j = 0; j < n; j++) {
int num = matrix[i][j];
num2indexList.putIfAbsent(num, new ArrayList<int[]>());
num2indexList.get(num).add(new int[]{i, j});
}
for (List<int[]> indexList : num2indexList.values()) {
int[] arr1 = indexList.get(0);
int i1 = arr1[0], j1 = arr1[1];
for (int k = 1; k < indexList.size(); k++) {
int[] arr2 = indexList.get(k);
int i2 = arr2[0], j2 = arr2[1];
uf.union(i1, j1, i2, j2);
}
}
}
for (int j = 0; j < n; j++) {
Map<Integer, List<int[]>> num2indexList = new HashMap<Integer, List<int[]>>();
for (int i = 0; i < m; i++) {
int num = matrix[i][j];
num2indexList.putIfAbsent(num, new ArrayList<int[]>());
num2indexList.get(num).add(new int[]{i, j});
}
for (List<int[]> indexList : num2indexList.values()) {
int[] arr1 = indexList.get(0);
int i1 = arr1[0], j1 = arr1[1];
for (int k = 1; k < indexList.size(); k++) {
int[] arr2 = indexList.get(k);
int i2 = arr2[0], j2 = arr2[1];
uf.union(i1, j1, i2, j2);
}
}
}
int[][] degree = new int[m][n];
Map<Integer, List<int[]>> adj = new HashMap<Integer, List<int[]>>();
for (int i = 0; i < m; i++) {
Map<Integer, int[]> num2index = new HashMap<Integer, int[]>();
for (int j = 0; j < n; j++) {
int num = matrix[i][j];
num2index.put(num, new int[]{i, j});
}
List<Integer> sortedArray = new ArrayList<Integer>(num2index.keySet());
Collections.sort(sortedArray);
for (int k = 1; k < sortedArray.size(); k++) {
int[] prev = num2index.get(sortedArray.get(k - 1));
int[] curr = num2index.get(sortedArray.get(k));
int i1 = prev[0], j1 = prev[1], i2 = curr[0], j2 = curr[1];
int[] root1 = uf.find(i1, j1);
int[] root2 = uf.find(i2, j2);
int ri1 = root1[0], rj1 = root1[1], ri2 = root2[0], rj2 = root2[1];
degree[ri2][rj2]++;
adj.putIfAbsent(ri1 * n + rj1, new ArrayList<int[]>());
adj.get(ri1 * n + rj1).add(new int[]{ri2, rj2});
}
}
for (int j = 0; j < n; j++) {
Map<Integer, int[]> num2index = new HashMap<Integer, int[]>();
for (int i = 0; i < m; i++) {
int num = matrix[i][j];
num2index.put(num, new int[]{i, j});
}
List<Integer> sortedArray = new ArrayList<Integer>(num2index.keySet());
Collections.sort(sortedArray);
for (int k = 1; k < sortedArray.size(); k++) {
int[] prev = num2index.get(sortedArray.get(k - 1));
int[] curr = num2index.get(sortedArray.get(k));
int i1 = prev[0], j1 = prev[1], i2 = curr[0], j2 = curr[1];
int[] root1 = uf.find(i1, j1);
int[] root2 = uf.find(i2, j2);
int ri1 = root1[0], rj1 = root1[1], ri2 = root2[0], rj2 = root2[1];
degree[ri2][rj2]++;
adj.putIfAbsent(ri1 * n + rj1, new ArrayList<int[]>());
adj.get(ri1 * n + rj1).add(new int[]{ri2, rj2});
}
}
Set<Integer> rootSet = new HashSet<Integer>();
int[][] ranks = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int[] rootArr = uf.find(i, j);
int ri = rootArr[0], rj = rootArr[1];
rootSet.add(ri * n + rj);
ranks[ri][rj] = 1;
}
}
Queue<int[]> queue = new ArrayDeque<int[]>();
for (int val : rootSet) {
if (degree[val / n][val % n] == 0) {
queue.offer(new int[]{val / n, val % n});
}
}
while (!queue.isEmpty()) {
int[] arr = queue.poll();
int i = arr[0], j = arr[1];
for (int[] adjArr : adj.getOrDefault(i * n + j, new ArrayList<int[]>())) {
int ui = adjArr[0], uj = adjArr[1];
degree[ui][uj]--;
if (degree[ui][uj] == 0) {
queue.offer(new int[]{ui, uj});
}
ranks[ui][uj] = Math.max(ranks[ui][uj], ranks[i][j] + 1);
}
}
int[][] res = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int[] rootArr = uf.find(i, j);
int ri = rootArr[0], rj = rootArr[1];
res[i][j] = ranks[ri][rj];
}
}
return res;
}
}
class UnionFind {
int m, n;
int[][][] root;
int[][] size;
public UnionFind(int m, int n) {
this.m = m;
this.n = n;
this.root = new int[m][n][2];
this.size = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
root[i][j][0] = i;
root[i][j][1] = j;
size[i][j] = 1;
}
}
}
public int[] find(int i, int j) {
int[] rootArr = root[i][j];
int ri = rootArr[0], rj = rootArr[1];
if (ri == i && rj == j) {
return rootArr;
}
return find(ri, rj);
}
public void union(int i1, int j1, int i2, int j2) {
int[] rootArr1 = find(i1, j1);
int[] rootArr2 = find(i2, j2);
int ri1 = rootArr1[0], rj1 = rootArr1[1];
int ri2 = rootArr2[0], rj2 = rootArr2[1];
if (ri1 != ri2 || rj1 != rj2) {
if (size[ri1][rj1] >= size[ri2][rj2]) {
root[ri2][rj2][0] = ri1;
root[ri2][rj2][1] = rj1;
size[ri1][rj1] += size[ri2][rj2];
} else {
root[ri1][rj1][0] = ri2;
root[ri1][rj1][1] = rj2;
size[ri2][rj2] += size[ri1][rj1];
}
}
}
}
\ No newline at end of file
[[217, 317], [225, 358]]
\ No newline at end of file
[[20, -21, 14], [-19, 4, 19], [22, -47, 24], [-19, 4, 19]]
\ No newline at end of file
[[4, 2, 3], [1, 3, 4], [5, 1, 6], [1, 3, 4]]
\ No newline at end of file
[[7, 3, 6], [1, 4, 5], [9, 8, 2]]
\ No newline at end of file
[[5, 1, 4], [1, 2, 3], [6, 3, 1]]
\ No newline at end of file
[[2, -2, 1], [9, 4, 7], [12, 17, 24], [3, 5, 8]]
\ No newline at end of file
[[3, 1, 2], [5, 2, 3], [6, 7, 8], [4, 5, 6]]
\ No newline at end of file
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
\ No newline at end of file
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
\ No newline at end of file
[[11, 21, 13], [42, 35, 26], [27, 18, 69], [120, 121, 132]]
\ No newline at end of file
[[1, 3, 2], [5, 4, 3], [2, 1, 4], [6, 7, 8]]
\ No newline at end of file
[[121, 221, 123], [422, 315, 226], [327, 148, 619], [120, 321, 232]]
\ No newline at end of file
[[2, 4, 3], [6, 5, 4], [3, 1, 6], [1, 6, 5]]
\ No newline at end of file
[[27, 17], [25, 58]]
\ No newline at end of file
# 数组排序
给你一个整数数组 nums ,请你将数组按照每个值的频率 降序 排序。如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。
请你返回排序后的数组。
参数限制:
1 <= nums.length <= 100
-100 <= nums[i] <= 100
## 输入描述
整数数组 nums
## 输出描述
按照要求排序后的数组
# 示例
## 输入:
[2, 3, 1, 1, 3]
## 输出:
[3, 3, 1, 1, 2]
## 提示
输出样例说明: '3' 频率为 2,'1' 频率为 2,'2' 频率为 1 。
class Solution {
public int[] frequencySort(int[] nums) {
Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();
for (int num : nums) {
cnt.put(num, cnt.getOrDefault(num, 0) + 1);
}
List<Integer> list = new ArrayList<Integer>();
for (int num : nums) {
list.add(num);
}
Collections.sort(list, (a, b) -> {
int cnt1 = cnt.get(a), cnt2 = cnt.get(b);
return cnt1 != cnt2 ? cnt2 - cnt1 : b - a;
});
int length = nums.length;
for (int i = 0; i < length; i++) {
nums[i] = list.get(i);
}
return nums;
}
}
\ No newline at end of file
[1, 1, 1, 2, 2, 2, 3, 3, 3, 3]
\ No newline at end of file
[3, 3, 3, 3, 2, 2, 2, 1, 1, 1]
\ No newline at end of file
[1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
\ No newline at end of file
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 1]
\ No newline at end of file
[2, 3, 1, 1, 3]
\ No newline at end of file
[2, 1, 1, 2, 2, 3, 1, 3, 2]
\ No newline at end of file
[2, 2, 2, 2, 1, 1, 1, 3, 3]
\ No newline at end of file
[2, 3, 1, 3, 2, 1, 4, 2]
\ No newline at end of file
[2, 2, 2, 3, 3, 1, 1, 4]
\ No newline at end of file
[2, 3, 1, 5, 5, 7, 8, 9, 3, 2, 1, 4, 2]
\ No newline at end of file
[2, 2, 2, 5, 5, 3, 3, 1, 1, 9, 8, 7, 4]
\ No newline at end of file
[2, 3, 1, 3, 2, 3, 1, 1, 1]
\ No newline at end of file
[1, 1, 1, 1, 3, 3, 3, 2, 2]
\ No newline at end of file
[-1, 1, -6, 4, 5, -6, 1, 4, 1]
\ No newline at end of file
[1, 1, 1, 4, 4, -6, -6, 5, -1]
\ No newline at end of file
[10, 10, 20, 20, 50, 60, 11, 40, 10, 10, 20, 20, 50, 60, 11, 40, 10, 10, 20, 20, 50, 60, 11, 40, 10]
\ No newline at end of file
[10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 60, 60, 60, 50, 50, 50, 40, 40, 40, 11, 11, 11]
\ No newline at end of file
[1, 1, 2, 2, 3, 3, 3, 4, 4, 4]
\ No newline at end of file
[4, 4, 4, 3, 3, 3, 2, 2, 1, 1]
\ No newline at end of file
## 选择题
1. 下列哪种数据库模型是基于关系代数理论的?
A. 层次数据库模型
B. 网状数据库模型
C. 关系数据库模型
D. 对象数据库模型
答案:C
解析:关系数据库模型是基于关系代数理论的,它使用关系来表示数据,关系之间通过键值关联。层次数据库模型和网状数据库模型是早期的数据库模型,它们使用树形结构或网状结构来组织数据。对象数据库模型是基于对象的,它使用面向对象的概念来处理数据。
2. 大数据的“3V”指的是哪三个方面?
A. 速度、体积、价值
B. 速度、体积、多样性
C. 速度、价值、多样性
D. 体积、价值、多样性
答案:B
解析:大数据的“3V”指的是Velocity(速度)、Volume(体积)和Variety(多样性)。 大数据是指数据量巨大到无法使用传统数据库管理系统进行处理的数据。大数据具有3V特点:Volume(数据量大)、Velocity(数据产生速度快)和Variety(数据多样性)。例如,社交媒体平台每天产生海量的用户生成内容,如推文、照片和视频等,这些数据量大、产生速度快且具有多样性。此外,还有一些学者提出了新的“4V”,即Value(价值),将大数据的价值也作为一个重要的维度来考虑。
3. 下列哪种技术可以用于大数据处理?
A. MapReduce
B. SQL
C. NoSQL
D. 手写代码
答案:A
解析:MapReduce是一种用于大数据处理的分布式计算模型。它可以将大数据集分成许多小的数据块进行并行处理,然后将结果整合在一起。SQL和NoSQL都是用于数据存储的技术,而不是数据处理的技术。手写代码虽然可以完成大数据处理,但是不如使用现有的技术方便和高效。
4. OLAP(联机分析处理)是指什么?
A. 一种数据库管理系统
B. 一种数据仓库
C. 一种数据处理技术
D. 一种数据挖掘算法
答案:C
解析:OLAP(Online Analytical Processing,联机分析处理)是一种数据处理技术,用于多维数据分析和查询。它可以对大量数据进行快速的复杂分析和查询,以支持商业智能和决策支持系统。数据仓库则是存储数据的地方,而OLAP是对数据仓库中的数据进行处理和分析的技术。
5. ACID是什么意思?
A. 一种数据库管理系统
B. 一种数据仓库
C. 一种数据处理技术
D. 一种数据库事务保证的特性
答案:D
解析:ACID是数据库事务的四个核心特性,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。原子性指事务是一个不可分割的操作序列,要么全部执行成功,要么全部失败回滚;一致性指事务执行前后数据库的状态保持一致;隔离性指多个事务并发执行时,彼此之间是相互隔离的;持久性指事务执行成功后,对数据库的修改必须永久保存在数据库中。
## 问答题
1. 什么是关系型数据库?请举例说明。
答案:关系型数据库是一种基于关系代数理论的数据库模型,使用表格(即关系)来表示和管理数据。关系由行和列组成,每行表示一个记录,每列表示一个属性。关系型数据库的数据可以通过 SQL 语言进行查询、修改、删除等操作。
举例说明:MySQL、Oracle、Microsoft SQL Server 等都是关系型数据库的典型代表。比如,我们可以创建一个名为“students”的表格,其中包含学生的姓名、年龄、性别、学号等属性,每行表示一个学生的信息,如下所示:
| 姓名 | 年龄 | 性别 | 学号 |
| ---- | ---- | ---- | ---- |
| 张三 | 20 | 男 | 1001 |
| 李四 | 21 | 女 | 1002 |
| 王五 | 19 | 男 | 1003 |
2. 大数据技术有哪些常见的应用场景?请举例说明。
答案:大数据技术在许多领域都有广泛的应用,以下是其中几个常见的应用场景:
- 金融行业:通过分析大量金融数据,预测市场趋势、风险管理、欺诈检测等。
- 健康医疗行业:通过分析大量健康数据,提高疾病诊断的准确性和效率、发现新的治疗方法等。
- 零售行业:通过分析大量销售数据,进行精准营销、库存管理、供应链优化等。
- 物流行业:通过分析大量物流数据,进行路线规划、运输调度、交通流量预测等。
举例说明:以金融行业为例,银行可以通过大数据技术对客户进行分析,预测客户的偏好、行为,从而制定个性化的营销策略;同时,也可以通过大数据技术进行风险管理,对客户的信用、欺诈等进行监测和预测,提高风险管控能力和业务运营效率。
3. 数据仓库是什么?它有哪些优点?
答案:数据仓库是一种专门用于存储和管理企业历史数据的数据库,旨在为企业决策支持提供数据支持。数据仓库通常由多个数据源组成,通过ETL(Extract-Transform-Load)工具将多个数据源中的数据整合到一起,形成一个统一的、可供分析的数据集。数据仓库中的数据通常是面向主题的,即按照业务领域进行划分和整理。
数据仓库的优点主要包括:
- 支持决策支持:数据仓库提供了一个可供分析的数据集,使得企业能够进行高效、全面、灵活的数据分析和挖掘,从而支持企业的决策。
- 面向主题:数据仓库中的数据按照业务领域进行划分和整理,使得数据的结构更加清晰、易于理解和使用。
- 支持大数据量:数据仓库通常存储大量历史数据,能够支持企业处理大数据量的需求。
- 数据质量高:数据仓库中的数据经过ETL等多个环节的整理和清洗,使得数据的质量更高、更可靠。
- 高性能:数据仓库通常采用冷热分离、索引等技术,使得数据的查询和分析更加快速和高效。
4. OLAP(联机分析处理)与 OLTP(联机事务处理)有何区别?
答案:OLAP(Online Analytical Processing,联机分析处理)和OLTP(Online Transaction Processing,联机事务处理)是两种不同的数据处理方式,它们有以下区别:
- 数据类型:OLAP通常处理历史数据或聚合数据,而OLTP处理当前的实时数据或交易数据。
- 数据分析:OLAP用于多维数据分析和查询,支持复杂的分析和聚合操作,而OLTP主要用于事务处理和数据增删改查操作。
- 数据量:OLAP通常处理大量数据,而OLTP处理的数据量相对较小。
- 数据结构:OLAP使用多维数据结构,如数据立方体(Data Cube),而OLTP使用传统的关系型数据库结构。
- 数据模式:OLAP面向主题,即按照业务领域进行划分和整理,而OLTP面向应用,即按照应用程序的需求进行设计。
5. 数据库事务是什么?请举例说明。
答案:数据库事务是指由一个或多个操作组成的逻辑工作单元,这些操作要么全部成功执行,要么全部回滚。事务具有四个特性,即ACID(原子性、一致性、隔离性、持久性)。
举例说明:假设一个银行系统中有两个账户A和B,现在需要将100元从账户A转移到账户B。这个过程可以分为两个步骤:首先从账户A中扣除100元,然后将100元存入账户B中。如果这两个步骤中的任何一个出现错误,比如账户余额不足,就需要回滚整个操作,保证数据的一致性。这个过程可以通过事务来实现,将这两个步骤放在一个事务中,如果两个步骤都执行成功,则提交事务,否则回滚事务。这样可以保证数据的一致性和完整性。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册