【算法】數據結構與算法基礎總覽(中)——刷Leetcode等算法題時一些很實用的jdk輔助方法錦集

        最近重新學習數據結構與算法以及刷leetcode算法題時,發現不少jdk自帶的方法可以提升刷題的效率。這些小技巧不僅僅對刷算法題帶來便利,對我們平時開發也是很有幫助的。本文以java語言爲基礎,記錄了目前已經使用或看到過的一些小技巧,後續在刷題過程中,還會持續更新。

 

一、數組

  1、使用Arrays.sort(int[] a)進行排序

      底層採用的是快速排序算法實現的:時間複雜度爲O(nlogn),空間複雜度O(logn),不穩定。默認是從小到大排序。

int[] arr = new int[]{2, 9, 6, 8, 4, 3};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));

打印結果:

[2, 3, 4, 6, 8, 9]

參數可以是其它基本數據類型,也可以是自定義類型,可以通過使用Comparator比較器來自定義排序順序。

例如,降序排列:

1 Integer[] arr = new Integer[]{2, 9, 6, 8, 4, 3};
2 Arrays.sort(arr, new Comparator<Integer>() {
3     @Override
4     public int compare(Integer t0, Integer t1) {
5         return t1 - t0;
6     }
7 });
8 System.out.println(Arrays.toString(arr));

打印結果:

[9, 8, 6, 4, 3, 2]

  2、使用Arrays.toString(int[] arr)將數組組合成字符串

     內部是通過StringBuilder + for 循環來實現的,該方法可以方便調試查看數組的值,而無需自己手動來組裝字符串。

int[] arr = new int[]{2, 9, 6, 8, 4, 3};
System.out.println(Arrays.toString(arr));

打印結果:

[2, 9, 6, 8, 4, 3]

同樣,該方法的參數數組類型可以是其它數據類型。

  3、使用Arrays.fill()一次性給數組填充指定值

       有時候我們需要將數組中的所有元素都初始化填充爲指定值,一般的做法是通過循環來一一賦值,這樣做顯然不夠簡潔。所幸,java sdk中提供了簡潔的方法來一步實現,如下所示:

int[] arr = new int[10];
Arrays.fill(arr,1);
System.out.println(Arrays.toString(arr));

打印結果:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

實際上fill()內部實現也是通過for循環一一賦值的,但對開發者使用而言,確實簡潔了很多。

 

二、ArrayList

  1、使用構造函數或者addAll將一個集合中的內容添加到新的ArrayList中

//構造函數
public ArrayList(Collection<? extends E> c) 
//addAll方法
public boolean addAll(Collection<? extends E> c) 

內部實現原理:ArrayList內部維護了一個數組,無論是使用構造函數還是addAll方法,都是將給定集合中的元素複製到該數組中。

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<Integer> newList1 = new ArrayList<>(list);
System.out.println(newList1);
List<Integer> newList2 = new ArrayList<Integer>();
newList2.addAll(list);
System.out.println(newList2);

打印結果:

[1, 2, 3]
[1, 2, 3]

  2、ArrayList與數組互相轉化

    (1)使用list.toArray()將ArrayList轉爲數組

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Object[] a = list.toArray();
System.out.println(Arrays.toString(a));

打印結果:

[1, 2, 3]

    (2)使用Arrays.asList(數組) 將數組轉爲ArrayList

Integer[] arr = new Integer[]{2, 9, 6, 8, 4, 3};
List<Integer> arrList = Arrays.asList(arr);
System.out.println("size=" + arrList.size() + ";arrList=" + arrList);

打印結果:

size=6;arrList=[2, 9, 6, 8, 4, 3]

  3、使用Collections.reverse(list) 倒轉ArrayList中的元素

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Collections.reverse(list);
System.out.println(list);

打印結果:

[3, 2, 1]

  4、使用Set來過濾具有相同元素的list

Set<List<String>> set = new HashSet<>();
List<String> list1 = Arrays.asList("a", "b");
List<String> list2 = Arrays.asList("a", "b");
set.add(list1);
set.add(list2);
System.out.println(list1 == list2);
System.out.println(set);

打印結果:

false
[[a, b]]

從打印結果可知,list1和list2不是同一個對象,但其中包含的元素一樣(內容和順序都一樣),Set就只會保存第一個加入的list。目前只發現set中添加的List對象時有這個特性,如果使用數組,或者StringBuilder等引用型對象就不生效,且如果兩個list中元素順序不一致,也不會有過濾效果。

 

三、HashMap

    1、在new HashMap對象時,初始化其中的內容

public Map<String, String> map = new HashMap() {
        {
            put("k1", "v1");
            put("k2", "v2");
        }
    };

System.out.println(map);

打印結果:

{k1=v1, k2=v2}

使用該方法後,就不用專門在某個方法中通過put來添加內容,無疑,在很多場景下可以帶來不少便利。

    2、類似於ArrayList類,HashMap也可以通過構造函數或者putAll()方法,一次將已知的hashMap內容添加進來:

//方式一(map爲上一節中的對象):
Map<String,String> newMap = new HashMap(map);
//方式二:
Map<String,String> newMap = new HashMap();
newMap.putAll(map);

System.out.println(newMap);

打印結果:

{k1=v1, k2=v2}

 

四、字符串

  1、按照多個空格,對字符串進行分割:split(“\\s+”)或者split(" +")

    例如:

String s = "leetcode    is     very     good!";
String[] arr = s.split("\\s+"); //或者s.split(" +");
System.out.println(Arrays.toString(arr));

打印結果:

[leetcode, is, very, good!]

  2、去掉字符串首尾空字符串:trim()

1 String s = "  ab cd   ";
2 Sytem.out.println(s.trim());

打印結果:

ab cd

  3、拼接字符串:join()

1 String[] strArray = {"ab","cd","ef"};
2 System.out.println(String.join(" ",strArray));

打印結果:

ab cd ef

這裏將數組組合成字符串,用“ ”連接。join的第一個參數可以替換其它的連接符號,第二個參數除了使用數組外,還可以使用LIst,Deque等集合對象

 

 五、位運算

       機器世界計算和存儲最終使用的數據格式都是二進制,採用位運算可以更加貼近機器語言,提高計算效率(當今計算機新能如此強的情況下,一些小範圍使用位運算提升的效率看起來肯定是微乎其微,不過使用位運算逼格肯定提升一個檔次~~)。

  1、判斷奇偶

      以往判斷奇偶採用的都是 x % 2 == 1 和 x % 2 == 0 ,這裏我們可以使用&運算來判斷:

(x & 1) == 1 // 說明x爲奇數
(x & 1) == 0 // 說明x爲偶數

例如:

System.out.println("5是奇數嗎?:" + ((5 & 1) == 1));
System.out.println("5是偶數嗎?:" + ((5 & 1) == 0));
System.out.println("4是奇數嗎?:" + ((4 & 1) == 1));
System.out.println("4是偶數嗎?:" + ((4 & 1) == 0));

打印結果:

5是奇數嗎?:true
5是偶數嗎?:false
4是奇數嗎?:false
4是偶數嗎?:true

  2、除以2

       以往一個數x除以2的計算方式是x / 2,這裏採用位運算的方式爲:

x >> 1;//右移1位,表示除以2
x << 1;//左移1位,表示乘以2

例如:

System.out.println(5 >> 1);
System.out.println(5 << 1);

打印結果爲:

2
10   

(持續完善中......)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章