ArrayListy整理+源码解析+面试题+OJ题(杨辉三角)


ArrayList

  • ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
  • 在任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬
    移,故时间复杂度为O(N)
  • 扩容需要申请新空间,拷贝数据,释放旧空间,同时存不满会产生资源浪费

一、 ArrayList的使用

1. ArrayList的构造方法

1.1源码分析

无参构造的时候,并没有对它底层的elementData数组分配内存
在这里插入图片描述

而是在第一次调用add方法的时候,对底层的elementData数组分配内存且大小为10;
在这里插入图片描述

ArrayList的扩容是1.5倍进行的

有参构造时,传的参数直接在构造的时候对数组进行内存分配
在这里插入图片描述
在这里插入图片描述

传的参数类型是E或者E的子类,并且一定实现了Collection接口

 public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        list.add(4);
        list.add(3);
        list.add(2);
        ArrayList<Number> arrayList = new ArrayList<>(list);//实例化对象,调用构造方法
        arrayList.add(1);
        System.out.println(arrayList);
    }
    [4, 3, 2, 1]

2.ArrayList的方法

2.1 add方法

在这里插入图片描述

2.2 remove方法
 		arrayList.remove(3);//删除索引的元素
        arrayList.remove(new Integer(4));//删除指定的Integer类型的元素

通过new一个指定的类型,进行装箱,来进行删除

2.3 subList 方法
List<Number> subList = arrayList.subList(0, 2);
        System.out.println(subList);
        System.out.println("-------------");
        //[4, 3, 5, 2, 1]
        //[4, 3]
        subList.set(0,99);
        System.out.println(subList);
        System.out.println(arrayList);
        //[99, 3]
        //[99, 3, 5, 2, 1]

1.左闭右开
2.两者公用同一个elementData数组,修改截取的内容,原内容也会改变

二、ArrayList的遍历

1. for循环

  for (int i = 0; i < arrayList.size(); i++) {
            System.out.print(arrayList.get(i)+" ");//99 3 5 2 1
        }

2. foreach

 for (Number x:arrayList) {
            System.out.print(x+" ");
        }

3. 迭代器

 ListIterator<Number> it = arrayList.listIterator();//迭代器
        while (it.hasNext()){
            System.out.print(it.next()+" ");
        }

1.先判断it有没有下一个数
2.如果有,it向下走,并打印,没有:循环结束

三、 ArrayList的应用

1.CVTE面试题

S1 = “welcome to cvte”;
S2 = “come”;

要求在S1中删除在S2中出现过的字符

ArrayLIst写法
public static void main(String[] args) {
        String s1 = "welcome to cvte";
        String s2 = "come";
        //wltvt
        ArrayList<Character> arrayList1 = new ArrayList<>();
        for (int i = 0; i < s1.length(); i++) {
            char c = s1.charAt(i);
            if (!s2.contains((c + ""))) {  //c+"" 变成一个字符串
                arrayList1.add(c);
            }
        }
        System.out.println(arrayList1);
        for(int i = 0;i<arrayList1.size();i++){
            System.out.print(arrayList1.get(i));
        }
    }

1.先遍历字符串s1,拿到每个字符
2.在s2中进行比较,如果没有,存进arrayList
3.打印arrayList

StringBuilder写法
  public static void main(String[] args) {
        String s1 = "welcome to cvte";
        String s2 = "come";
        //wltvt
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < s1.length(); i++) {
            char c = s1.charAt(i);
            if (s2.indexOf(c)==-1){
                stringBuilder.append(c);
            }
        }
        String res = stringBuilder.toString();
        System.out.println(res);
    }

2.杨辉三角


上图可以转化为:
在这里插入图片描述

思路

1.List的嵌套,看成二维数组来解决问题

2.左右两侧都是1
中间的元素,等于该列上一行的元素,加上前一列前一行的元素

在这里插入图片描述

方法

1.先将1存进第一行
2.将第一行数组存进顺序表中
3.在循环中,创建当前行的数组,并拿到前一行的数组

  • 这里注意,因为已经存了一个数组,所以外层循环是i从1开始,numRows前结束

4.同样先在当前行数组存一个1

  • 这里的内循环,同理 j从1开始,直到i之前,因为i的值等于当前行元素个数

5.取的前一行的当前列与前一行的前一列的元素之和,存进当前行
6.在当前行最后存一个1
5.将当前行,存进顺序表中

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret = new ArrayList<>();
        List<Integer> row = new ArrayList<>();
        row.add(1);//把1存进row数组
        ret.add(row);//把row数组存进ret数组
        for (int i = 1; i < numRows; i++) {
            List<Integer> curRow = new ArrayList<>();
            List<Integer> pervRow = ret.get(i - 1);//基于当前i的前一行
            curRow.add(1);//开头的1
            for (int j = 1; j < i; j++) {//开头是1,j从1 开始,i的值恰好为最后一个数的下标,j小于i
                int x = pervRow.get(j) + pervRow.get(j - 1);//前一行的当前列加上前一行的前一列
                curRow.add(x);//存进当前行
            }
            curRow.add(1);//最后的1
            ret.add(curRow);
        }
        return ret;
    }
}

点击移步博客主页,欢迎光临~

偷cyk的图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值