454.四数相加II
首先定义一个map,可以存放A和B两数之和,value存放出现的次数,然后遍历a和b。之后遍历层,d并采用变量count计数
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer,Integer> map=new HashMap<>();
for(int a:nums1){
for(int b:nums2){
if(map.containsKey(a+b)){
map.put(a+b, map.get(a+b) + 1);
}else{
map.put(a+b,1);
}
}
}
int count=0;
for(int c:nums3){
for(int d:nums4){
int temp=0-c-d;
if(map.containsKey(temp)) count+=map.get(temp);
}
}
return count;
}
}
383. 赎金信
注意:字符串要转换为字符数组
s.toCharArray()
先看长度是否符合要求,接着统计出现的次数,之后遍历ransomNote看是否合乎要求
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(ransomNote.length()>magazine.length()) return false;
int[] r= new int[26];
for(int c:magazine.toCharArray()){
r[c-'a']++;
}
for(int c:ransomNote.toCharArray()){
r[c-'a']--;
if(r[c-'a']<0) return false;
}
return true;
}
}
15. 三数之和
排序,定1找2,双指针,注意去重
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {
return result;
}
if (i > 0 && nums[i] == nums[i - 1]) { // 去重a
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (right > left) {
int sum = nums[i] + nums[left] + nums[right];
if (sum > 0) {
right--;
} else if (sum < 0) {
left++;
} else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while (right > left && nums[right] == nums[right - 1])
right--;
while (right > left && nums[left] == nums[left + 1])
left++;
right--;
left++;
}
}
}
return result;
}
}
18. 四数之和
需要考虑溢出问题,使用long
思路和三数之和类似,可以与四叔相加II对比一下
出现问题
- 限制一下 j,小于长度-2,而不是小于长度
- y应该是continue,而不是return result(最关键的一步)。
代码
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.println("i:" + i);
// nums[i] > target 直接返回, 剪枝操作
if (nums[i] > 0 && nums[i] > target) {
return result;
}
if (i > 0 && nums[i - 1] == nums[i]) { // 对nums[i]去重
continue;
}
for (int j = i + 1; j < nums.length-2; j++) {
System.out.println(" j:" + j);
// nums[i]+nums[j] > target 直接返回, 剪枝操作
if (nums[i] + nums[j] > 0 && nums[i] + nums[j] > target) {
continue;
}
if (j > i + 1 && nums[j - 1] == nums[j]) { // 对nums[j]去重
continue;
}
int left = j + 1;
int right = nums.length - 1;
System.out.println(" left:" + left + " right:" + right);
while (right > left) {
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
if (sum > target) {
right--;
} else if (sum < target) {
left++;
} else {
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
System.out.println(" left:" + left + " right:" + right);
System.out.println(" " + nums[i] + " " + nums[j] + " " + nums[left] + " " + nums[right]);
// 对nums[left]和nums[right]去重
while (right > left && nums[right] == nums[right - 1])
right--;
while (right > left && nums[left] == nums[left + 1])
left++;
left++;
right--;
}
}
System.out.println("");
}
System.out.println("i:" + i + " end");
}
return result;
}
}