記一下leetcode刷題經驗
第一題最簡單的兩數之和,題目長這樣: //給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。
思路: ①一上來直接暴力解法選擇陣列的一個 x 值,然後逐個遍歷陣列,找到數值等於 target-x 的值,記錄下標,返回,但是暴力解法時間複雜度達到了 O(n²),空間複雜度 O(1);
②改用雜湊解法,使用雜湊表,可以將尋找 target - x 的時間複雜度降低到從 O(N) 降低到 O(1),對於每一個 x,我們首先查詢雜湊表中是否存在 target - x,然後將 x 插入到雜湊表中,即可保證不會讓 x 和自己匹配。
class Solution { public int[] twoSum(int[] nums, int target) { HashMap<Integer,Integer> map = new HashMap<>(); //建立一個輔助的雜湊表 for(int i = 0; i < nums.length; i ++){ //遍歷 int tmp = target - nums[i]; //作差 if(map.containsKey(tmp)){ //判斷return new int[2]{map.get(tmp),i} //返回匹配結果 } map.put(nums[i],i); } return new int[0]; //未匹配返回 } }
第二題是兩數相加,題目長這樣子: 給出兩個 非空 的連結串列用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式儲存的,並且它們的每個節點只能儲存 一位 數字。如果,我們將這兩個數相加起來,則會返回一個新的連結串列來表示它們的和。
思路: 依舊藉助雜湊表,由於輸入的兩個連結串列都是逆序儲存數字的位數的,因此兩個連結串列中同一位置的數字可以直接相加。同時遍歷兩個連結串列,逐位計算它們的和,並與當前位置的進位值相加。如果兩個連結串列的長度不同,則可以認為長度短的連結串列的後面有若干個 0 。此外,如果連結串列遍歷結束後,進位符不等於 0 ,還需要在結果的連結串列後面附加一個節點,節點的值為 進位 的值 。
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode pre = new ListNode(0); ListNode cur = pre; int carry = 0; while (l1 != null || l2 != null) { int x = l1 == null ? 0 : l1.val; int y = l2 == null ? 0 : l2.val; int sum = x + y + carry; carry = sum / 10; sum = sum % 10; cur.next = new ListNode(sum); cur = cur.next; if (l1 != null) { l1 = l1.next; } if (l2 != null) { l2 = l2.next; } } if(carry == 1) { cur.next = new ListNode(carry); } return pre.next; }
第三題是比較經典的滑動視窗問題,題目如下: 給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。
思路: 這個題目一上來就可以知道用滑動視窗去解決,利用雜湊表,逐漸遍歷字串,記錄當前最長不重複子串長度,往下遍歷發現重複字元則更改指標,再往下遍歷,同時更新此時的最長不重複子串的長度。
class Solution { public int lengthOfLongestSubstring(String s) { int n = s.length(); int count = 0; Map<Character, Integer> map = new HashMap<>(); for (int start = 0,end = 0;end < n; end++) { char c = s.charAt(end); if(map.containsKey(c)) { start = Math.max(map.get(c),start); } count = Math.max(count,end - start + 1); map.put(c, end + 1); } return count; } }
總結:前幾道題目是比較簡單的型別,思路很好想到,但是轉變為程式碼的能力太差,繼續多看多做吧!