数组
数组是用来存储数据的集合,但是,通常我们会发现把数组看作一个存储具有相同类型 的变量集合会更有用。无须声明单个变量。一旦数组被创建,它的大小是固定的。使用一个數组引用变量,通过下标来访 问數组中的元素。
数组变量的声明
为了在程序中使用数组,必须声明一个引用数组的变量,并指明数组的元索类型。下面 是声明数组变量的语法:
elementType[] arrayRefVar;(元素类型[]数组引用变量;)
elementType 可以是任意数据类型,但是数组中所有的元素都必须具有相同的数据类 型。
数组的创建
不同于基本数据类型变量的声明,声明一个数组变量时并不在内存中给数组分配任何空 间。它只是创建一个对数组的引用的存储位置。如果变量不包含对数组的引用,那么这个 变量的值为 null。除非数组已经被创建,否则不能给它分配任何元素。声明数组变量之后, 可以使用下面的语法用 nev* 操作符创建数组,并且将它的引用賦给一个变量: arrayRefVar = new e1ementType[arrayS1ze]: 这条语句做了两件事情: 1 ) 使用 new elementType[arrayS"ize]创建了一个数组; 2) 把这个新创建的数组的引用陚值给变暈 arrayRefVar。 声明一个数组变量、创建数组、然后将数组引用賦值给变量这三个步驟可以合并在一条 语句里,如下所示:
elementType[]arrayRefVar =new elementType[arraySize]; (元素类型[]数组引用变量 =new 元素类型[ 数组大小]; )
或elementType arrayRefVar[] * new e1ementType[arraySize]; (元素类型数组引用变量 =new 元素类型[数组大小])
数组的大小和默认值
当给数组分配空间时,必须指定该数组能够存储的元素个数,从而确定数组大小。创 建数组之后就不能再修改它的大小。可以使用 arrayRefVar.length 得到数组的大小。例如: myList.length 为 10。 当创建数组后,它的元素被賦予默认值,数值型基本数据类型的默认值为 0, char 型的 默认值为’\u0000’,boolean 型的默认值为 false。
对数组的处理——遍历、查找、扩容、排序
具体代码实现:
public static void main(String[] args){
//1.数组的遍历
bianli();
//2.数组的查找
find();
//3.数组的扩容
resize();
//4.数组的排序
//4.1选择排序O(n^2)
selectedSort();
//4.2冒泡排序O(n^2)
bubbleSort();
//4.3插入排序O(n^2)
insertSort();
}
public static void bianli(){
int[] arr={1,2,3,4,5,6};
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void find(){
//线性查找
//最好情况O(1)
//最坏情况O(n)
//平均情况O(n)
int[] arr={3,6,5,2,5,9,7};
int key=9;//找元素key的角标
int index=-1;
for(int i=0;i<arr.length;i++){
if(arr[i]==key){
index=i;
break;
}
}
System.out.print(index);
System.out.println();
//二分查找O(logn)
//前提是数组必须是有序的
arr=new int[]{1,2,3,4,5,6,7,8,9};
key=7;
index=-1;
int minindex=0;
int maxindex=arr.length-1;
int midindex=(minindex+maxindex)/2;
while(true){
if(arr[midindex]>key){
maxindex=midindex-1;
}else if(arr[midindex]<key){
minindex=midindex+1;
}else{
index=midindex;
break;
}
midindex=(midindex+maxindex)/2;
if(minindex>maxindex){
break;
}
}
System.out.print(index);
System.out.println();
}
public static void resize(){
int[] arr=new int[]{1,2,3,4,5};
int deltSize=2;//-缩 +扩
int[] newarr=new int[arr.length+deltSize];
//将原先的数据放入新的数组中
for(int i=0;i<Math.min(arr.length,newarr.length);i++){
newarr[i]=arr[i];
}
arr=newarr;
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void selectedSort(){
int[] arr=new int[]{5,2,7,8,3,1,9,6,4};
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void bubbleSort(){
int[] arr=new int[]{5,2,7,8,3,1,9,6,4};
for(int i=0;i<arr.length-1;i++){//i 表示轮数
for(int j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
int t=arr[j];
arr[j]=arr[j+1];
arr[j+1]=t;
}
}
}
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void insertSort(){
int[] arr=new int[]{5,2,7,8,3,1,9,6,4};
for(int i=1;i<arr.length;i++){
int e=arr[i];
int j=i-1;
while(j>=0&&arr[j]>e){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=e;
}
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
运行结果:
示例1:
本题采用三种思路解题:
思路一:
数据:存储数字的数组nums 存储次数的数组counts
步骤:
1.获取一个数字
2.判断该数字
2.1如果是0 跳出循环
2.2如果不是
当前数字是否在nums中
在 相应counts位置++
不在 nums扩容将数字传进去 counts扩容
3.排序nums 同时counts
*/
import java.util.*;
class Class29{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int[] nums=new int[0];//存储数字
int[] counts=new int[0];//存储次数
System.out.print("请输入数字:");
while(true){
int number=scanner.nextInt();
if(number==0){//输入0则跳出循环
break;
}
int index=indexof(nums,number);//获取number的角标
if(index!=-1){
counts[index]++;
}else{
nums=addnum(nums,number);
counts=addcount(counts);
}
}
sort(nums,counts);
for(int i=0;i<nums.length;i++){
System.out.println(nums[i]+" occurs "+counts[i]+(counts[i]>1?" times ":" time "));
}
}
public static int indexof(int[] nums,int number){
for(int i=0;i<nums.length;i++){
if(nums[i]==number){
return i;
}
}
return -1;
}
public static int[] addnum(int[] nums,int number){
int[] arr=new int[nums.length+1];
for(int i=0;i<nums.length;i++){
arr[i]=nums[i];
}
arr[arr.length-1]=number;
return arr;
}
public static int[] addcount(int[] counts){
int[] arr=new int[counts.length+1];
for(int i=0;i<counts.length;i++){
arr[i]=counts[i];
}
return arr;
}
public static void sort(int[] nums,int[] counts){
for(int i=1;i<nums.length;i++){
int e=nums[i];
int f=counts[i];
int j=i-1;
while(j>=0&&nums[j]>e){
nums[j+1]=nums[j];
counts[j+1]=counts[j];
j--;
}
nums[j+1]=e;
counts[j+1]=f;
}
}
}
运行结果:
思路二:
用时间换空间
*/
import java.util.*;
class Class29_2{
public static void main(String[] args){
int[] arr=new int[0];
Scanner scanner=new Scanner(System.in);
System.out.println("请输入数字:");
while(true){
int num=scanner.nextInt();
if(num==0){
break;
}
arr=addnumber(arr,num);
}
sort(arr);
for(int i=0;i<arr.length;){
int count=1;
for(int j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){
count++;
}else{
break;
}
}
System.out.println(arr[i]+" occurs "+count+(count>1?" times ":" time "));
i=i+count;
}
}
public static void sort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
public static int[] addnumber(int[] arr,int num){
int[] newarr=new int[arr.length+1];
for(int i=0;i<arr.length;i++){
newarr[i]=arr[i];
}
newarr[newarr.length-1]=num;
return newarr;
}
}
运行结果为:
class Class29_3{
public static void main(String[] args){
int[] arr=new int[101];
Scanner scanner=new Scanner(System.in);
System.out.print("请输入数字:");
while(true){
int num=scanner.nextInt();//这里num指代数组角标
if(num==0){//题目所给循环终止条件
break;
}
arr[num]++;
}
for(int i=1;i<arr.length;i++){
if(arr[i]>0){
System.out.println(i+" occurs "+arr[i]+(arr[i]>1?"times":"time"));
}
}
}
}
运行结果为:
示例2:
该题也有三种思路:
具体代码:
步骤:
1.读入一个数字
2.判断该数字是否存在于数组中
不存在 扩容 存进去
存在 不管
*/
import java.util.*;
class Class30{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
System.out.print("请输入十个数:");
int[] arr=new int[0];//扩容
for(int i=0;i<10;i++){
int num=scanner.nextInt();
if(!isnuminarr(arr,num)){
arr=add(arr,num);
}
}
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
public static boolean isnuminarr(int[] arr,int num){
for(int i=0;i<arr.length;i++){
if(arr[i]==num){
return true;
}
}
return false;
}
public static int[] add(int[] arr,int num){
int[] newarr=new int[arr.length+1];
for(int i=0;i<arr.length;i++){
newarr[i]=arr[i];
}
newarr[newarr.length-1]=num;
return newarr;
}
}
思路:
在输入数字的同时,进行重复的消除
步骤:
1.读入一个数字
2.判断该数字是否以存在于数组中
不存在 进去
存在 不管
*/
import java.util.*;
class Class30_2{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
System.out.print("请输入十个数:");//有效个数
int[] arr=new int[10];
int size=0;
for(int i=0;i<arr.length;i++){
int num=scanner.nextInt();
if(!isnuminarr(arr,num,size)){
arr[i]=num;
size++;
}
}
for(int i=0;i<size;i++){
System.out.print(arr[i]+" ");
}
}
public static boolean isnuminarr(int[] arr,int num,int size){
for(int i=0;i<size;i++){
if(arr[i]==num){
return true;
}
}
return false;
}
}
思路:
在输入数字之后,再进行重复的消除
*/
import java.util.*;
class Class30_3{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
System.out.print("请输入十个数:");
int[] arr=new int[10];//有效个数
for(int i=0;i<arr.length;i++){
arr[i]=scanner.nextInt();
}
sort(arr);//先排序
int size=arr.length;//再进行重复消除
for(int i=arr.length-1;i>0;i--){
if(arr[i]==arr[i-1]){
for(int j=i;j<size;j++){
arr[j-1]=arr[j];
}
size--;
}
}
for(int i=0;i<size;i++){
System.out.print(arr[i]+" ");
}
}
public static void sort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
}
}
}
}
运行结果:
示例3:
class Class32{
public static void main(String[] args){
//1.输入球的个数(路径的个数)和槽子的个数
//2.定义槽子的个数
//3.计算路径后再统计
//路径的个数就是球的个数 路径随机生成几次 slotsCount-1次
//4.生成路径
Random random=new Random();//输入球的个数和槽子的个数
Scanner scanner=new Scanner(System.in);
System.out.print("请输入球的个数:");
int ballcount=scanner.nextInt();
System.out.print("请输入机器的槽数:");
int slotscount=scanner.nextInt();
int[] slots=new int[slotscount];//定义槽子的数组
for(int i=0;i<ballcount;i++){//计算路径后再统计,路径的个数就是球的个数 路径随机生成几次 slotsCount-1次
String path="";//生成路径
for(int j=0;j<slotscount-1;j++){
path=path+(random.nextInt(2)==0?"L":"R");
}
System.out.println(path);
int Rcount=gerR(path);
slots[Rcount]++;
}
for(int i=0;i<slots.length;i++){
System.out.println(slots[i]);
}
int max=getMax(slots);
for(int i=max;i>0;i--){
for(int j=0;j<slots.length;j++){
if(i<=slots[j]){
System.out.print("O");
}else{
System.out.print(" ");
}
}
System.out.println();
}
}
public static int getMax(int[] slots){
int max=slots[0];
for(int i=0;i<slots.length;i++){
if(slots[i]>max){
max=slots[i];
}
}
return max;
}
public static int gerR(String path){//字符串本质上就是字符数组
int Rcount=0;
for(int i=0;i<path.length();i++){
if(path.charAt(i)=='R'){//查看字符串中某个位置的内容
Rcount++;
}
}
return Rcount;
}
}
运行结果:
示例4:
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
*/
class LC66{
public static void main(String[] args){
int[] arr=new int[]{1,2,3};
arr=plusOne(arr);
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
public static int[] plusOne(int[] digits){
int carry=1;//进位
int num;
for(int i=digits.length-1;i>=0;i--){
num=digits[i]+1;
digits[i]++;
carry=num/10;
if(carry==0){
return digits;
}
digits[i]=0;
}
int[] arr=new int[digits.length+1];
arr[0]=1;
return arr;
}
}
运行结果:
示例5:
给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。
我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。
如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。
示例 1:
输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。
*/
class LC724{
public static void main(String[] args){
int[] arr=new int[]{1,7,3,6,5,6};
System.out.print(pivotIndex(arr));
}
public static int pivotIndex(int[] nums) {
if(nums.length<2){
return -1;
}
int sum=0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
}
int rightsum=0;
int leftsum=0;
for(int i=0;i<nums.length;i++){
if(i==0){
leftsum=0;
}else{
leftsum=leftsum+nums[i-1];
}
rightsum=sum-leftsum-nums[i];
if(leftsum==rightsum){
return i;
}
}
return -1;
}
}