代码随想录算法训练营
今日任务
454.四数相加II ,383. 赎金信 ,15. 三数之和 ,18. 四数之和
454.四数相加II
//很笨的方法,将结果全都保留判断
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
HashMap<Integer,Integer> hashMap=new HashMap<>();
int sum;
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
sum=nums1[i]+nums2[j];
if(!hashMap.containsKey(sum)){
hashMap.put(sum,1);
}else{
Integer value = hashMap.get(sum);
value=value+1;
hashMap.put(sum,value);
}
}
}
int count=0;
for (int i = 0; i < nums3.length; i++) {
for (int j = 0; j < nums4.length; j++) {
sum=(nums3[i]+nums4[j])*(-1);
if(hashMap.containsKey(sum)){
count=count+hashMap.get(sum);
}
}
}
return count;
}
}
383. 赎金信
//暴力解法
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
HashMap<Character,Integer> hashMap=new HashMap<>();
char[] magChar = magazine.toCharArray();
for (int i = 0; i < magChar.length; i++) {
char c=magChar[i];
if(!hashMap.containsKey(c)){
hashMap.put(c,1);
}else{
Integer value = hashMap.get(c);
value=value+1;
hashMap.put(c,value);
}
}
boolean flag=false;
int count=0;
char[] ranChar=ransomNote.toCharArray();
for (int i = 0; i < ranChar.length; i++) {
char c=ranChar[i];
if(!hashMap.containsKey(c)){
break;
}else{
Integer value = hashMap.get(c);
value=value-1;
if(value>=0){
hashMap.put(c,value);
}else{
break;
}
count++;
}
}
if(count==ransomNote.length()){
flag=true;
}
return flag;
}
}
15. 三数之和
//非常暴力的,超时了哈哈哈,我好菜
//就算改为treeset也还是会超时,但是第二个方法改为treeset能勉强过
public static List<List<Integer>> baoli1(int[] nums) {
List<List<Integer>> result=new ArrayList<>();
HashMap<Integer,Integer> hashMap=new HashMap<>();
int sum=0;
for (int s = 0; s < nums.length; s++) {
if (!hashMap.containsKey(nums[s])) {
hashMap.put(nums[s], 1);
sum = sum + nums[s];
for (int i = 0; i < nums.length; i++) {
if (i != s) {
for (int j = 0; j < nums.length; j++) {
if (j != s&&j!=i) {
if (sum + nums[i] + nums[j]== 0) {
//将s i j从小到大排序
List<Integer> list = new ArrayList<>();
list.add(nums[s]);
list.add(nums[i]);
list.add(nums[j]);
Collections.sort(list);
if (!result.contains(list)) {
result.add(list);
}
}
}
}
}
}
sum=0;
}
}
return result;
}
//去重改为treeset不会超时,虽然还是很慢
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
HashMap<Integer,Integer> hashMap=new HashMap<>();
List<List<Integer>> result=new ArrayList<>();
Set<List<Integer>> hashSet = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
if(!hashMap.containsKey(nums[i])){
hashMap.put(nums[i],1);
}else{
Integer value = hashMap.get(nums[i]);
hashMap.put(nums[i],value+1);
}
}
Set<Integer> keySet = hashMap.keySet();
Iterator<Integer> iterator = keySet.iterator();
while(iterator.hasNext()){
Integer key = iterator.next();
Integer value = hashMap.get(key);
if(value>=3){
//3-2-1判断
if(key*3==0){
//3个,不需要别的
List<Integer> list = new ArrayList<>();
list.add(key);
list.add(key);
list.add(key);
hashSet.add(list);
}
}
if(value>=2){
hashMap.put(key,value-2);
if(hashMap.containsKey(0-key*2)&&hashMap.get(0-key*2)!=0){
//2个,且找到了
List<Integer> list = new ArrayList<>();
list.add(key);
list.add(key);
list.add(0-key*2);
Collections.sort(list);
hashSet.add(list);
}
hashMap.put(key,value);
}
if(value>=1){
hashMap.put(key,value-1);
//判断1个时
HashMap<Integer,Integer> newhash=new HashMap<>();
newhash.putAll(hashMap);
newhash.remove(key);
Set<Integer> keySet1 = newhash.keySet();
Iterator<Integer> iterator1 = keySet1.iterator();
while(iterator1.hasNext()){
Integer key1 = iterator1.next();
Integer value1 = newhash.get(key1);
newhash.put(key1,value1-1);
int n=(0-key-key1);
if(newhash.containsKey(n)&&newhash.get(n)!=0){
//1个,且找到了
List<Integer> list = new ArrayList<>();
list.add(key);
list.add(key1);
list.add(n);
Collections.sort(list);
hashSet.add(list);
}
newhash.put(key1,value1);
}
hashMap.put(key,value);
}
}
for (List<Integer> list : hashSet) {
result.add(list);
}
return result;
}
}
//看了题解,但没完全贴上去重b和c的,自己用了treeset
//核心:双指针法,尽量减少for循环
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//先给nums排序
Arrays.sort(nums);
List<List<Integer>> result=new ArrayList<>();
Set<List<Integer>> hashSet = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
//如果nums[0]就已经比0大了,则直接return
if(nums[0]>0){
return result;
}
//去重a
if(i>0&&nums[i]==nums[i-1]){
continue;
}
int left=i+1;
int right=nums.length-1;
while(left<right){
if(nums[i]+nums[left]+nums[right]>0){
right--;
}else if(nums[i]+nums[left]+nums[right]<0){
left++;
}else{
List<Integer> list=new ArrayList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
Collections.sort(list);
hashSet.add(list);
left++;
right--;
}
}
}
for (List<Integer> list : hashSet) {
result.add(list);
}
return result;
}
}
18. 四数之和
//小心之和超过int的范围
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result=new ArrayList<>();
Set<List<Integer>> hashSet = new HashSet<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
//去重
if(i>0&&nums[i]==nums[i-1]){
continue;
}
for (int j = i+1; j < nums.length; j++) {
int left=j+1;
int right=nums.length-1;
while(left<right){
//四个1000000000会超int
long sum=(long) nums[i]+nums[j]+nums[left]+nums[right];
if(sum<target){
left++;
}else if(sum>target){
right--;
}else{
List<Integer> list=new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);
Collections.sort(list);
hashSet.add(list);
left++;
right--;
}
}
}
}
for (List<Integer> list : hashSet) {
result.add(list);
}
return result;
}
}