文章目录
1. 将数组转换为字符串
1.1 第一种方法是 JAVA 中 JDK 里自带的方法:
// 将数组转换为字符串
String arrStr = Arrays.toString(arr);
1.2 第二种自己实现的方法:
// 将数组转换为字符串
public static String arr2Str(int[] arr) {
// 任意数据类型转换为字符串使用+
String ret = "[";
for (int i = 0; i < arr.length; i++) {
ret += arr[i];
if (i != arr.length - 1) {
ret += ", ";
}
}
ret += "]";
return ret;
}
2. 复制数组,将一个数组复制到另一个新的数组
2.1 整体复制
2.1.1 第一种方法是 JAVA 中 JDK 里自带的方法:
// 复制数组
int[] newArr = Arrays.copyOf(arr, arr.length);
这种方法, newArr 和 arr 引用的是同一个地址。
2.1.2 第二种自己实现的方法:
// 复制数组(全复制)
public static int[] copyArr(int[] arr) {
int[] result = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
result[i] = arr[i];
}
return result;
}
这种方法是开辟了一个新空间保存数组,arr 和 result 指向的不是一个地址。
2.2 部分复制
2.2.1 第一种方法是 JAVA 中 JDK 里自带的方法:
// [1,2,3] 复制(1,2)结果为[2]
int[] newArr2 = Arrays.copyOfRange(arr, 1, 2);
这种方法部分复制时,只复制左边界值,不复制右边界值,也就是左闭右开。
2.2.2 第二种自己实现的方法:
// 部分复制数组
public static int[] copyRangeArr(int[] arr, int start, int end) {
int[] result = new int[end - start];
for (int i = start; i < end; i++) {
result[i - start] = arr[i];
}
return result;
}
3. 找数组中的最大值
// 找数组中的最大值
public static int arrMax(int[] arr) {
// 先让最大值等于当前数组的第一个元素
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
// 如果 arr[i] 大于当前最大值,使 arr[i] 等于最大值
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
4. 求整型数组的和
4.1 暴力解法
// 暴力求解
public static int sum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
4.2 递归解法
递归解法的条件:1. 大问题可以划分成小问题 2. 大问题和小问题除了数据规模不一样,其他都一样 3. 有终止
public static int sumRecursion(int[] arr, int start, int end) {
// 终止条件,区间为0
if (end == start) {
return arr[end];
} else {
// 求和可以划分成前一个和后面全部的和
return arr[start] + sumRecursion(arr, start + 1, end);
}
}
5. 求整型数组的平均值
// 求平均值
public static double avg(int[] arr) {
double result = 0.0;
int sum = sum(arr);
result = (double) sum / arr.length;
return result;
}
6. 如何判断数组是一个有序的集合
// 如何判断数组是一个有序的集合(升序)
public static boolean isSorted(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
return false;
}
}
return true;
}
7. 查找数组中的目标元素
7.1 暴力解法
// 暴力求解
public static int toFind(int[] arr, int toFind) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == toFind) {
return i;
}
}
// 没有找到
return -1;
}
暴力求解的效率低,当查找的数组数据达到万级,亿级甚至更大,暴力求解使用的时间就会很长。
7.2 二分查找(分治思想)
// 二分查找 前提是个有序数组(升序)
public static int toFind2(int[] arr, int toFind) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == toFind) {
return mid;
} else if (arr[mid] < toFind) {
// 此时待查找元素大于中间元素,大于左边所有元素
left = mid + 1;
} else if (arr[mid] > toFind) {
// 此时待查找元素小于中间元素,小于右边所有元素
right = mid - 1;
}
}
return -1;
}
面试题: 如何在一个大小10万的数据集中快速找到第k个元素?
// 先进行集合排序,然后二分查找
public static int bigFind(int[] arr, int toFind) {
int left = 0, right = arr.length - 1;
while (left <= right) {
count++;
int mid = (left + right) / 2;
if (arr[mid] == toFind) {
return mid;
} else if (arr[mid] < toFind) {
// 此时待查找元素大于中间元素,大于左边所有元素
left = mid + 1;
} else if (arr[mid] > toFind) {
// 此时待查找元素小于中间元素,小于右边所有元素
right = mid - 1;
}
}
return -1;
}
8. 数组排序
冒泡排序:每次将当前元素和下一个元素进行比较,如果当前元素大将当前元素与下一个元素两两交换,每进行一次循环都会有一个元素到达最终位置。
public static void bubbleSort(int[] arr) {
// 未排序数组[0....arr.length - 1]
for (int i = 0; i < arr.length - 1; i++) {
// 处理还没有排序的元素[0....arr.length - 1 - i],因为排好的元素已经放在最后了
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
9. 数组的逆序排列
// 双引用法
// [1,2,3,4,5] -> [5,4,3,2,1]
// 过程:[5,2,3,4,1] [5,4,3,2,1]
public static void reverseArr(int[] arr) {
int left = 0, right = arr.length - 1;
while (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
10. 数组数字排列
将奇数放在数组前半部分,偶数放在后半部分:
public static void transform(int[] arr) {
int even = 0, odd = arr.length - 1;
while (even < odd) {
// 先从前面找到第一个偶数,过滤掉奇数
while (arr[even] % 2 != 0 && even < odd) {
even++;
}
// 从后面找到第一个奇数,过滤奇数
while (arr[odd] % 2 == 0 && even < odd) {
odd--;
}
// 交换奇数偶数位置,把奇数放在前面,偶数放在后面
int temp = arr[odd];
arr[odd] = arr[even];
arr[even] = temp;
}
}