数组练习题

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;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值