最近重新學習資料結構與演算法以及刷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
(持續完善中......)