⑤Java数组经典例题

Java数组经典例题


前言

这篇博客是记录在学完Java数组后,对于一些与数组操作相关的经典例题的记录。


一、杨辉三角形

1.1 杨辉三角形的特性

  • 他的两条斜边都是数字1组成,其余的数等于他肩上的两数之和
  • 每行数字左右对称,由1开始,逐渐增大
  • 第n行的数字个数为n
  • 第n行的数字之和为2^n-1;
    在这里插入图片描述

1.2 解题思路

  • 每一行的行首和行尾均为1,其他均为他肩上的两数之和,可以按照这两个特点将其分为两个部分赋值;第一部分先给首末元素赋值,然后再在第二部分给非首末元素赋值。
  • 关键:给非首末元素赋值
    arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
    

1.3 完整代码

public static void pascalTri() {
        //1.声明并初始化二维数组
        int[][] arr = new int[10][];

        //2.给二维数组赋值
        for(int i = 0; i<arr.length; i++) {
            //2.1初始化
            arr[i] = new int[i + 1];

            //2.2给首末元素赋1
            arr[i][0] = arr[i][i] = 1;

            //2.3给非首末元素赋值
            for(int j = 1; j < arr[i].length - 1; j++) {
                arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
            }
        }

        //3.遍历二维数组
        for(int i = 0; i < arr.length; i++) {
            System.out.format("%" + (arr.length-i) + "s", " "); //输出空格字符串
            for(int j = 0; j < arr[i].length; j++) {

                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }

二、回形数

2.1 题目描述

  • 从键盘输入一个整数(1~20);则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。
  • 例如:
    • 输入数字2,则程序输出:
      1 2
      4 3
    • 输入数字3,则程序输出:
      1 2 3
      8 9 4
      7 6 5
    • 输入数字4, 则程序输出:
      1 2 3 4
      12 13 14 5
      11 16 15 6
      10 9 8 7

2.2 解题思路

  • 对于回形数的特点,不难观察出它只存在向右、向下、向左、向上四个方向的运动,不管题目要求的是赋值还是打印,都只有这四个方向,所以只需要对二维数组的下标进行操作,当达到当前边界时,转换方向继续遍历。

2.3 完整代码

  • 代码相对显得的繁琐,有4个if判断,但是理解起来较为简单直观,若要简化代码,可以将二维数据下标的变化也初始化为一个二维数组:(1, 0), (0, 1), (-1, 0), (0, -1);具体实现可以自己尝试。
public static void numberLoops() {
        Scanner scan = new Scanner(System.in);
        System.out.print("输入方阵大小:");
        int len = scan.nextInt();
        int[][] arr = new int[len][len];

        int sum = len * len; //计数,用于跳出循环
        //关键: k=1:right; k=2:down; k=3:left; k=4:up
        int k = 1; //先向右开始
        int i = 0, j = 0;
        for (int m = 1; m <= sum; m++) {
            if(k == 1) { //向右
                if(j < len && arr[i][j] == 0) {
                    arr[i][j++] = m; //当前行向右
                }else {
                    k = 2; //向右转向向下
                    i++; //向下一行
                    j--; //因为最后一次j++,j会超出当前边界,j--回到边界
                    m--; //不满足当前方向会退出本次循环,m+1, 退回到不符合当前方向的m
                }
            }else if(k == 2) { //向下
                if(i < len && arr[i][j] == 0) {
                    arr[i++][j] = m; //当前列向下
                }else {
                    k = 3; //向下转向向左
                    i--;  //因为最后一次i++,i会超出当前边界,i--回到边界
                    j--;  //当前行向左
                    m--;  //不满足当前方向会退出本次循环,m+1, 退回到不符合当前方向的m
                }
            }else if(k == 3) { //向左
                if(j >= 0 && arr[i][j] == 0) {
                    arr[i][j--] = m; //当前行向左
                }else {
                    k = 4; //向左转向向上
                    i--; //向上一行
                    j++; //因为最后一次j--,j会超出当前边界,j++回到边界
                    m--; //不满足当前方向会退出本次循环,m+1, 退回到不符合当前方向的m
                }
            }else if(k == 4) { //向上
                if(i >= 0 && arr[i][j] == 0) {
                    arr[i--][j] = m; //当前列向上
                }else {
                    k = 1; //向上转向向右
                    i++; //因为最后一次i--,i会超出当前边界,i--回到边界
                    j++; //向下
                    m--; //不满足当前方向会退出本次循环,m+1, 退回到不符合当前方向的m
                }
            }
        }

三、数组的基本操作

3.1 数组的复制

  • for循环复制
    int[] arrCopy = new int[arr.length];
        for(int i = 0; i < arr.length; i++) {
            arrCopy[i] = arr[i];
        }
    

3.2 数组的反转

  • 经典三段式交换两个数的值
    for(int i = 0; i < arr.length/2; i++) {
            int temp = arr[i];
            arr[i] = arr[arr.length-i-1];
            arr[arr.length-i-1] = temp;
        }
    

3.3 数组的查找

  • (1)线性查找
    	//线性查找
        int x = 5; //待查找数
        boolean isFlag = true;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == x) {
                System.out.println("线性查找成功!索引值为:" + i);
                isFlag = false;
                break;
            }
        }
        if(isFlag) {
            System.out.println("未找到。");
        }
    
  • (2)二分查找
    	//二分查找(前提数组有序)
        int xx = 7;
        int low = 0;
        int high = arr.length - 1;
        int mid = 0;
        boolean isFlag1 = true;
        while(low <= high) {
            mid = (low + high) / 2;
            if(xx == arr[mid]){
                System.out.println("二分查找成功!索引值为:" + mid);
                isFlag1 = false;
                break;
            }else if(xx > arr[mid]) {
                low = mid + 1;
            }else {
                high = mid - 1;
            }
        }
        if(isFlag1) {
            System.out.println("未找到。");
        }
    

四、排序算法

4.1 最简单的排序:冒泡排序

在这里插入图片描述

  • 下面贴代码
public static void arraySorted() {
        int[] arr = new int[]{43, 32, 76, -98, 5, 64, 13};

        //冒泡排序
        for(int i = 0; i < arr.length; i++) {
            for(int j = 0; j < arr.length-i-1; j++) {
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

4.2 最需要掌握的排序:快速排序

  • 快排的主要思想就是不断的从表的两端向中间进行扫描,将小的放到左边,大的放到右边,作为标准的元素放到中间,在将两边的子表作为下一次快排的主表,重复执行,直到排序完成。

在这里插入图片描述

  • 下面贴代码
/**
     * 快排入口函数
     * @param arr 待排序数组
     * @param low 数组起始
     * @param high 数组末尾
     */
    public static void quickSort(int[] arr, int low, int high) {
        if(low < high) {  //low==high 循环调出条件
            int pivotpos = qkSortPart(arr, low, high); //第一趟快排
            quickSort(arr, low, pivotpos-1); //递归快排pivot分界左边部分
            quickSort(arr, pivotpos+1, high); //递归快排pivot分界右边部分
        }
    }

    /**
     * 快速排序的核心部分
     * @param arr 待排序数组
     * @param low 数组起始
     * @param high 数组末尾
     * @return 一趟快排后数组的分界数
     */
    public static int qkSortPart(int[] arr, int low, int high) {
        int pivot = arr[low];  //快排的枢轴
        while(low < high) {
            while(low < high && arr[high] >= pivot) --high; //hign从右往左找小于pivot的数
            arr[low] = arr[high]; //将比pivot小的数放到其左边
            while(low < high && arr[low] <= pivot) ++low; //low从左往右找大于pivot的数
            arr[high] = arr[low]; //将比pivot大的数放在其右边
        }
        arr[low] = pivot; //将枢轴放到最终分界位置
        return low; //返回这个分界位置
    }

总结

以上就是在学习Java数组过程中遇见的经典例题,其中数组的查找和排序十分重要,这里排序只写了冒泡和快排,后续也会专门写一遍关于十大排序算法的博客,夯实数组的相关基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值