数组方法与使用。

1、什么是数组:

本质上让我们可以”批量“创建相同类型的变量
也是一种数据结构–顺序表
【注】数据结构即把一堆数据保存起来的结构,关心的是如何高效的读写数据,

2、数组的创建与初始化:

①数组的动态初始化

语法:数据类型[] 数组名称 = new 数组类型[]{}
数据类型[] 数组名称 = new 数组类型[number]

//eg
int[] arr = new int[]{1,2,3,4,5};
int[] arr = new int[5];
//创建数组时,若没有使用{}来初始化每个元素值,那么每个元素都是该数据类型的默认值

②数组的静态初始化

语法: 数据类型[] 数组名称 = {初始化数据};
【注】静态初始化时Java的语法糖,javac编译之后,就是动态初始化
语法糖:只存在编译期之前

//eg
int[] arr = {1,2,3,4,5}; 

3、数组的使用

3.1 获取一个数组的长度,使用数组名称.length
3.2 访问数组元素,使用数组名称[元素的索引],数组的索引从0开始,数组名.lengtg-1 结束。
【注】注意数组越界

4、数组的遍历

①for循环
②增强型for循环

public class Array{
	public static void main (String[] args){
		int[] arr1 = new int[]{1,2,3,4,5};
			for(int i= 0;i < arr1.length;i++){
				System.out.println(arr[i]+" ");
			}
			//增强型for循环
			//此处的i指从数组的第一个元素开始取值,第一次把第一个元素复制一份给i,第二次循环把第二个元素的值复制一份给i,以此类推,直到把整个数组遍历结束。
			//只能读取数组的元素值,无法修改,i是每个元素值的拷贝,并不是实实在在的数组元素。
			forint i : arr1){
				System.out.println(i +" ");
			}
	}
}
//输出结果:1 2 3 4 5

5、数组和方法之间的关系:
①数组作为方法的参数
创建一个方法接受一个任意的整型数组并打印

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        printArr(arr);
    }
    private static void printArr(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}

②关于引用数据类型的理解问题
实参:位于主方法的临时变量;形参:位于方法中的临时变量。

方法的调用就是在栈区进行的,每个方法的调用过程,就是一个栈帧的入栈以及出栈过程,是一种先进后出的结构(LIFO),方法的局部变量和形参都在其中存储。当方法调用结束出栈时,临时变量都是被销毁。

堆:

所有对象都在堆中存储,数组对象,类的实例化对象,接口的对象。
引用就是起了个”别名“。数组的引用实际上就是保存数组的首元素地址。

在这里插入图片描述

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2};
        printArr(arr);
        System.out.println(arr[0] + " "+arr[1]);
    }

    private static void printArr(int[] arr) {
        int temp = arr[0];
        arr[0] = arr[1];
        arr[1] = temp;
    }
}

内存图:
在这里插入图片描述

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2};
        printArr(arr);
        System.out.println(arr[0] + " "+arr[1]);
    }

    private static void printArr(int[] arr) {
        arr = new int[]{10,20};
        int temp = arr[0];
        arr[0] = arr[1];
        arr[1] = temp;
    }
}

内存图:
在这里插入图片描述
数组对象:
实实在在在堆中存储,所有new出来的都在堆中
数组的引用:
给这块数组起了个名字,保存这个数组对象的首地址。

数组练习:

1、数组对象转为字符串对象
Arrays.toString()方法
【注】dk中某些类后+s,这些是工具类,提供了大量有用的方法,直接调用即可。

import java.util.Arrays;
public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3};
        //JDK内置工具类
        String str = Arrays.toString(arr);
        System.out.println(str);
    }
}
//输出结果
//[1, 2, 3]

2、数组的复制
①Arrays.copyOf()方法

import java.util.Arrays;
public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3};
        //新数组长度小于原数组
        int[] arr1 = Arrays.copyOf(arr, 2);
        //新数组长度等于原数组
        int[] arr2 = Arrays.copyOf(arr, 3);
        //新数组长度大于原数组
        int[] arr3 = Arrays.copyOf(arr, 4);
        System.out.println(Arrays.toString(arr1));
        System.out.println(Arrays.toString(arr2));
        System.out.println(Arrays.toString(arr3));
    }
}
//输出结果
//[1, 2]
//[1, 2]
//[1, 2, 3, 0]

②Arrays.copyOfRange()方法

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6};
        //Arrays.copyOfRange方法复制从索引2到索引5的数组元素值
        int[] arr1 = Arrays.copyOfRange(arr, 2, 5);
        System.out.println(Arrays.toString(arr1));
    }
}
//输出结果
//[3, 4, 5]

3、给定一个数组找出这个数组的最大值

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6};
        //假定数组第一个元素值为最大值,遍历比大小。
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }
        System.out.println("数组最大值为:" + max);
    }
}
//输出结果
//数组最大值为:6

4、二分查找(仅升序或者降序)

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5,6,7,8,9};
        System.out.println(binarySearch(arr,4));
        System.out.println(binarySearch(arr,8));
        System.out.println(binarySearch(arr,11));
    }

    //找到返回索引没找到返回-1;
    public static int binarySearch(int[] arr, int toFind) {
        //开始位置
        int left = 0;
        //结束位置
        int rigth = arr.length - 1;
        //终止循环条件:left>right;
        while (left <= rigth) {
            int mid = (left + rigth) / 2;
            if (toFind < arr[mid]) {
                rigth = mid - 1;
            } else if (toFind > arr[mid]) {
                left = mid + 1;
            } else {
                //arr[mid]  =  toFind;
                System.out.print("找到该元素!");
                return mid;
            }
        }
        System.out.println("没有找到!");
        return -1;
    }
}
//输出结果
//找到该元素!3
//找到该元素!7
//没有找到!
//-1

递归写法:

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
        System.out.println(binarySearch(arr,3,0, arr.length-1));
        System.out.println(binarySearch(arr,6,0, arr.length-1));
        System.out.println(binarySearch(arr,11,0, arr.length-1));
    }
        
    public static int binarySearch(int[] arr, int toFind, int left, int right) {
        if (left > right) {
            return -1;
        }
        //还有元素,我只知道中间元素
        int mid = (left + right) / 2;
        if (arr[mid] == toFind) {
            return mid;
        } else if (toFind < arr[mid]) {
            return binarySearch(arr, toFind, left, mid - 1);
        }
         return binarySearch(arr, toFind, mid + 1, right);
    }
//输出结果
//2
//5
//-1

【注】当面对乱序时,可先将数组排序,后使用二分查找某元素,效率较遍历仍然很快。

5、判断数组是否是一个顺序数组

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 4};
        System.out.println(isSorteArray(arr));
    }

    public static boolean isSorteArray(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i] > arr[i + 1]) {
                return false;
            }
        }
        return true;
    }
}
//输出结果
//false

6、数组排序
①冒泡排序
在这里插入图片描述
核心思想:假设现在数组有n个元素,每遍历一次就将数组中最大值放在数组末尾,每进行一次遍历,就有一个元素到达了最终位置。
将整个数组分为两个子数组:
1、待排序的数组[0…n]
2、已经排好序的数组[]
每进行一次遍历,待排序的数组元素-1已排序好的数组元素+1。

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 3, 2, 5, 6, 9, 7, 8, 4};
        System.out.println(Arrays.toString(bubbleSorting(arr)));
    }

    public static int[] bubbleSorting(int[] arr) {
        int[] arr1 = null;
        //表示遍历的次数,每进行一次就有一个较大值到达位置
        for (int i = 0; i < arr.length; i++) {
            //待排序的数组[0--i-1],已排序[]
            //j+1<arr.length
            //-i表示已经排列好的元素个数
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    //交换数据
                    int temp = 0;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        return arr;
    }
}
//输出结果
//[1, 2, 3, 4, 5, 6, 7, 8, 9]

优化:
①最后一个元素已经有序不需要排序
②若本来就是升序就不需要排序

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7};
        System.out.println(Arrays.toString(bubbleSorting(arr)));
    }

    public static int[] bubbleSorting(int[] arr) {
        //表示遍历的次数,每进行一次就有一个较大值到达位置
        //i<arr.length-1;表示剩最后一个元素就已经有序,不需要遍历
        for (int i = 0; i < arr.length - 1; i++) {
            boolean isWsaped = false;
            //待排序的数组[0--i-1],已排序[]
            //j+1<arr.length
            //-i表示已经排列好的元素个数
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    isWsaped = true;
                    int temp = 0;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (!isWsaped) {
                //内存循环没有元素交换,整个数组已经有序,提前退出循环
                break;
            }
        }
        return arr;
    }
}
//输出结果
//[1, 2, 3, 4, 5, 6, 7]

7、升序或者降序的数组输出逆序

import java.util.Arrays;
public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
        reverse(arr);
    }

    public static void reverse(int[] arr) {
        int i = 0;
        int j = arr.length - 1;
        while (i < j) {
            int temp = 0;
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
        System.out.println(Arrays.toString(arr));
    }
}
//输出结果
//[8, 7, 6, 5, 4, 3, 2, 1]

8、数组的数字排列问题

题目:给定一个整型数组,将所有的偶数放在前半部分,将所有的奇数放在数组的后半部分
例{1,2,3,4,5,6}输出{6,2,4,3,5,1}

思路:
分别定义i,j从前从后找奇数和偶数,找到第一个奇数和第一个偶数,交换他们的值。

public class Thinking {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
        transform(arr);
    }

    public static void transform(int[] arr) {
        int i = 0;
        int j = arr.length - 1;
        while (i < j) {
            //i从前向后找到第一个奇数为止
            while (i < j && arr[i] % 2 == 0) {
                i++;
            }
            //此时i一定是落在了第一个奇数的位置
            //j从后向前找到第一个偶数位置
            while (i < j && arr[j] % 2 != 0) {
                j--;
            }

            //此时j一定是落在了第一个偶数的为位置
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
        System.out.println(Arrays.toString(arr));
    }
}
//输出结果
//[8, 2, 6, 4, 5, 3, 7, 1, 9]

9、给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标,你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
返回:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

import java.util.Arrays;
public class ClassPractic {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6};
        System.out.println(Arrays.toString(twoSum(arr, 6)));
        System.out.println(Arrays.toString(twoSum(arr, 9)));
        System.out.println(Arrays.toString(twoSum(arr, 5)));
    }

    //双引用法--双指针
    public static int[] twoSum(int[] arr, int target) {
        int[] arr1=new int[2];
        for (int i = 0; i < arr.length; i++) {
            for (int j = arr.length - 1; j > i; j--) {
                if (arr[i] + arr[j] == target) {
                    arr1[0] = i;
                    arr1[1] = j;
                    return arr1;
                }
            }
        }
        return arr1;
    }
}
//输出结果
//[0, 4]
//[0, 4]
//[0, 3]

10、给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
在这里插入图片描述

//方法一:双指针、计数器法
public class ClassPractic {
    public static void main(String[] args) {
        int[] arr = new int[]{2, 2, 1};
        int[] arr1 = new int[]{4, 1, 2, 1, 2};
        System.out.println("只出现一次的元素是:");
        System.out.println(findNum(arr));
        System.out.println(findNum(arr1));
    }

    //给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。
    // 找出那个只出现了一次的元素。
    public static int findNum(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            //定义一个计数器,由题可知只有一个元素出现了一次,那么出现相同的次数就是1
            // 只有它符合这个计数,所以当计数出现就返回它的元素值。
            int count = 0;
            for (int j = 0; j < arr.length; j++) {
                if (arr[i] == arr[j]) {
                    count++;
                }
            }
            if (count == 1) {
                return arr[i];
            }
        }
        return -1;
    }
}
//输出结果
//只出现一次的元素是:
//1
//4
//方法二:异或:同0异1
public class ClassPractic {
    public static void main(String[] args) {
        int[] arr = new int[]{2, 2, 1};
        int[] arr1 = new int[]{4, 1, 2, 1, 2};
        System.out.println("只出现一次的元素是:");
        System.out.println(findNum(arr));
        System.out.println(findNum(arr1));
    }

    //给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。
    // 找出那个只出现了一次的元素。
    public static int findNum(int[] arr) {
        int num = 0;
        for (int i : arr) {
            num ^= i;
        }
        return num;
    }
}
//输出结果
//只出现一次的元素是:
//1
//4

11、【注】:向下取整的运算称为Floor,用数学符号⌊⌋表示;向上取整的运算称为Ceiling,用数学符号⌈⌉表示。在这里插入图片描述

//方法一:双指针计数器
public class ClassPractic {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 2, 3};
        int[] arr1 = new int[]{2, 2, 1, 1, 1, 2, 2};
        System.out.println(majorityElement(arr));
        System.out.println(majorityElement(arr1));
    }

    public static int majorityElement(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            //设置一个计数器,由题目可只,当一个数出现次数大于n/2时它是多数元素
            //此时返回该元素值
            int count = 0;
            for (int j = 0; j < arr.length; j++) {
                if (arr[i] == arr[j]) {
                    count++;
                }
            }
            if (count > arr.length / 2) {
                return arr[i];
            }
        }
        return -1;
    }
}
//输出结果
//3
//2
//方法二:排序最中间的数必是最多元素。
public class ClassPractic {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 2, 3};
        int[] arr1 = new int[]{2, 2, 1, 1, 1, 2, 2};
        System.out.println(majorityElement(arr));
        System.out.println(majorityElement(arr1));
    }

    public static int majorityElement(int[] arr) {
       //排序
        Arrays.sort(arr);
        //位运算。  >>右移,同意于除2
        return arr[arr.length >> 1];
    }
}
//输出结果
//3
//2
//摩尔投票法
//假设第一个元素为第一个候选人,相同则投赞成票,不同则投反对票,
//赞成票+1反对票-1,当票数为0时,换候选人为当前投票人。
public class ClassPractic {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 2, 3};
        int[] arr1 = new int[]{2, 2, 1, 1, 1, 2, 2};
        System.out.println(majorityElement(arr));
        System.out.println(majorityElement(arr1));
    }

    public static int majorityElement(int[] arr) {
        int num = arr[0];
        //票数
        int count = 1;
        for (int i = 1; i < arr.length; i++) {
            if (num == arr[i]) {
                count++;
            } else {
                count--;
                if (count == 0) {
                    num = arr[i];
                    count =1;
                }
            }
        }
        return num;
    }
}
//输出结果
//3
//2

在这里插入图片描述
若在一组数中,至多选择m个元素,则该元素的得票数 >⌊ n/(m+1) ⌋
核心步骤:
1、选侯选人,票数为0更换候选人,直到整个数组扫描完毕
2、统计候选人的票数,看他是否满足 >⌊ n/(m+1) ⌋
摩尔投票法之选两个人

二维数组:

1、语法:

数据类型[][] 数组名称 = new 数据类型[行数][列数]{可选的初始化数据};

public class Thinking {
    public static void main(String[] args) {
        int[][] arr = new int[][]{
                {1, 2, 3},
                {2, 3, 4},
        };
        //行
        for (int i = 0; i < arr.length; i++) {
            //列
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }
    }
}
//输出
//1	 2	3	
//2  3	4	
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值