454.四數相加II
class Solution { public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { //前兩數相加,key是合,次數是value,跟後兩數相加的和等於0的話,就取出map裡的次數。 //兩個for loop 時間複雜度n方。 int res = 0; Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for(int i: nums1){ for(int j: nums2){ int sum = i + j; if(map.containsKey(sum)){ map.put(sum, map.get(sum) + 1); }else{ map.put(sum, 1); } } } for(int i: nums3){ for(int j: nums4){ int sum =0 - i - j; if(map.containsKey(sum)){ res += map.get(sum); } } } return res; } }
383. 贖金信
class Solution { public boolean canConstruct(String ransomNote, String magazine) { //注意java基本語法,寫法。 //用陣列,跟242是同一個思路 if(ransomNote.length() > magazine.length()){ return false; } int[] record = new int[26]; for(char c: magazine.toCharArray()){ record[c - 'a']++; } for(char d : ransomNote.toCharArray()){ record[d - 'a']--; if(record[d - 'a'] < 0){ return false; } } return true; } }
15. 三數之和
class Solution { public List<List<Integer>> threeSum(int[] nums) { //先排序,然後三個指標,迴圈i,然後i之後的最左指標跟最右指標 //重點是如何去重。for迴圈裡的每個while 都是在去重複。 List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); for(int i = 0; i < nums.length; i++){ if(nums[i] > 0){ return res; } if(i > 0 && nums[i] == nums[i - 1]){ continue; } int left = i + 1; int right = nums.length -1; while(left < right){ int sum = nums[i] + nums[left] + nums[right]; if(sum > 0){ right--; }else if(sum < 0){ left++; }else{ res.add(Arrays.asList(nums[i], nums[left], nums[right])); } while(right > left && nums[right] == nums[right -1]){ right--; } while(right > left && nums[left] == nums[left + 1]){ left--; } right--; left++; } } return res; } }
18. 四數之和 :兩次剪枝導致無法AC.註釋就好了
class Solution { public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> list =new ArrayList<>(); //排序 Arrays.sort(nums); for(int i = 0; i < nums.length; i++){ //第一次剪枝 /*if(nums[i] > 0 && nums[i] > target){ return list; }*/ //第一次去重 if(i > 0 && nums[i] == nums[i-1]){ continue; } for(int j = i + 1; j < nums.length; j++){ //第二次剪枝 /*if(nums[i] + nums[j] > 0 && nums[i] + nums[j] > target){ return list; }*/ //第二次去重 if(j > i + 1 && nums[j] == nums[j-1]){ continue; } //透過左右指標找到元素c,d int left = j + 1; int right = nums.length -1; while(left < right){ long sum = (long)nums[i] + nums[j] + nums[left] + nums[right]; if(sum < target){ left++; }else if(sum > target){ right--; }else{ list.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right])); //第三次去重 while(left < right && nums[left] == nums[left+1]){ left++; } while(left < right && nums[right] == nums[right - 1]){ right--; } left++; right--; } } } } return list; } }