Java刷题知识点

Java中的算法与数据结构

Posted by John Mactavish on August 21, 2019

前言

  刷LeetCode算法与数据结构题时碰到的知识点就放在这里,随时更新。如果需要临时准备C/C++或者的Go的编程题,就可以对照着快速看一下这些东西在其他语言中对应的实现。

正篇

字符串与整数转换

String 转换成 int

  1. int i = Integer.parseInt(String str);或 int i = Integer.parseInt(String str,int radix) 把使用指定基数radix的字符串转换成整数 (基数可以是 10, 2, 8, 或 16 等进制数)
  2. int i = Integer.valueOf(my_str).intValue();

字串转成 Double, Float, Long 的方法大同小异.如
double c = Double.parseDouble(“5”); //5.0

int 转换成 String

  1. String s = String.valueOf(i);
  2. String s = Integer.toString(i);
  3. String s = “” + i;

Double, Float, Long 转成字串的方法大同小异.

迭代器

Java5 引入了一种主要用于数组和集合的增强型 for 循环,增强 for 循环语法格式如下:

for(声明语句 : 表达式)
{
   //代码句子
}

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。 示例:

 int [] numbers = {10, 20, 30, 40, 50};
 for(int x : numbers ){
    System.out.print( x );
    System.out.print(",");
 }

缺点:

  1. 对于数组,不能方便的访问下标值;
  2. 对于集合,与使用Interator相比,不能方便的删除集合中的内容(在内部也是调用Interator).

除了简单遍历并读取其中的内容外,不建议使用增强的for循环。

Collection类

子接口是Set和List,集合中只能放置对象的引用,不能放置原生数据类型,所以我们需要使用原生数据类型的封装类才能加入到集合中(如用Integer代替int)。 有Ordered与Sorted接口:

  • Ordered排序,按照某种由具体情况决定的顺序排序,是后天指定的
  • Sorted排序,按照天然顺序进行排序,是先天指定的

列表List

实现类包括LinkedList,Vector,ArrayList。

  1. ArrayList依赖于数组实现的,初始长度为10的Object[],并且可随需要而增加的动态数组。当元素超过10,那么ArrayList底层会新生成一个数组,长度为原来的1.5倍+1, 然后将原数组内容复制到新数组中,并且后续增加的内容会放到新数组中,当新数组无法容纳增加的元素,重复该过程。
    ArrayList对随机访问性能很好,但进行大量插入,删除操作,性能很差,因为操作之后后续元素需要移动。
  2. Vector,历史比较悠久,Java诞生就有了,特点与ArrayList相同,不同的是Vector操作元素的方法是同步的,同一时刻只能有一个线程访问,没有特殊需求都使用ArrayList。 更常用的是Vector的子类Stack。
  3. LinkedList功能与ArrayList,Vector相同,内部是依赖双链表实现的,因此有很好的插入和删除性能,但随机访问元素的性能很差。

注:ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:

  • list.toArray();
  • list.toArray(T[] a);

对于第一个重载方法,是将list直接转为Object[] 数组;第二种方法是将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。 如果用第一个时是这样写:

ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < 10; i++) {
    list.add(""+i);
}
 String[] array= (String[]) list.toArray();
 

结果一运行,报错:

Exception in thread “main” java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

原因一看就知道了,不能将Object[] 转化为String[],转化的话只能是取出每一个元素再转化。 java中的强制类型转换只是针对单个对象的,想要偷懒将整个数组转换成另外一种类型的数组是不行的。 应当这样写:

String[] array = list.toArray(new String[list.size()]);

集合Set

实现类HashSet,LinkedHashSet。子接口SortSet实现类TreeSet。Set特点是不包含重复元素,最多包含一个null,元素没有顺序。

  1. HashSet存储对象引用时是按照哈希策略来实现的,HashSet中是否存在一个对象是通过equals()和hashCode()协同判断,HashSet底层是使用HashMap实现的。
  2. LinkedHashSet是Ordered,采用双链表实现的,有固定顺序,也就是插入顺序,LinkedHashSet底层是使用LinkedHashMap实现的。
  3. TreeSet是SortedSet接口的实现,元素不论以什么元素插入,在遍历的时候,都会以天然顺序遍历,TreeSet底层是使用TreeMap实现的。 因为TreeSet是带排序的,所以想要为TreeSet增加自定义类型,必须指定排序规则。

分离整数各位数

class Solution {//判断一个数是否是回文数
    public boolean isPalindrome(int x) {
        int z=10;
        if(x==0)
            return true;
        if(x<0||x%10==0)
            return false;
        if(x<=9)
            return true;

        int div=1;
        while(x/div>=10){
            div*=10;
        }//获取和x位数相同的整10倍数div

        int i,j;
        while(div>=z/100){  
            i=x/div%10;//从左到右分离,除数 div 和被分离位 i 位数相同
            div/=10;
            //System.out.printf("i=%d,div=%d\n",i,div);

            j=(x%z)/(z/10);//从右到左分离,除数 z 比被分离位 j 位数高一位
            z*=10;
            //System.out.printf("j=%d,z=%d\n",j,z);
            if(i!=j)
                return false;
        }
        return true;
}
}

更加一般的方法如下

<>

参考

CSDN博主「遇见美好」
CSDN博主「itlwc」


最后附上GitHub:https://github.com/gonearewe