代码随想录算法训练营第七天 | LeetCode454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和
一、 LeetCode454.四数相加II
1. 题目链接
LeetCode454.四数相加II
2. 学习资料:
3. 思路
嵌套循环遍历nums1和nums2,假设值为a+b,之后再嵌套遍历剩下两个数组记为c+d。 因为a+b+c+d = 0; 所以 a+b = 0-c+d 所以当遍历剩下两个数组的和时,如果map集合中出现过0-c+d的值,那么就出现了满足题目要求的组合。 使用HashMap这个结构,key用来存a+b, value用来存 a+b出现的次数 result返回值每一次增加的次数是value的值。
4. 代码
class Solution {
public int fourSumCount ( int [ ] nums1, int [ ] nums2, int [ ] nums3, int [ ] nums4) {
Map < Integer , Integer > map = new HashMap < > ( ) ;
int result = 0 ;
for ( int i : nums1) {
for ( int j : nums2) {
int temp = i+ j;
if ( map. containsKey ( temp) ) {
map. put ( temp, map. get ( temp) + 1 ) ;
} else {
map. put ( temp, 1 ) ;
}
}
}
for ( int i: nums3) {
for ( int j: nums4) {
int temp = i+ j;
if ( map. containsKey ( 0 - temp) ) {
result = result+ map. get ( 0 - temp) ;
}
}
}
return result;
}
}
二、 LeetCode383. 赎金信
2. 学习资料:
3. 思路
该题思想上很像LeetCode242有效的字母异位词 有题目可知,题目给的两个字符串中的字符都由小写字母组成,因此可以用数组结构来存储字母出现的次数。 遍历ransomNote中出现的字符,并映射到对应的数组位置中,对应数组位置的元素+1。 遍历magazine中出现的字符,并映射到对应数组的位置中,对应数组位置的元素-1。 最后遍历这个存放结果的数组,如果有大于0的数,说明不能组成。
4. 代码
class Solution {
public boolean canConstruct ( String ransomNote, String magazine) {
int [ ] record = new int [ 26 ] ;
for ( char c : ransomNote. toCharArray ( ) ) {
record [ c- 'a' ] += 1 ;
}
for ( char c : magazine. toCharArray ( ) ) {
record [ c- 'a' ] -= 1 ;
}
for ( int i: record ) {
if ( i> 0 ) {
return false ;
}
}
return true ;
}
}
三、 LeetCode15. 三数之和
2. 学习资料:
3. 思路
利用双指针的思想
4. 代码
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 ) {
break ;
}
if ( i> 0 && nums[ i] == nums[ i- 1 ] ) {
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] ) ) ;
while ( left< right && nums[ right] == nums [ right- 1 ] ) {
right-- ;
}
while ( left< right && nums[ left] == nums [ left+ 1 ] ) {
left++ ;
}
left++ ;
right-- ;
}
}
}
return result;
}
}
四、 LeetCode18. 四数之和
2. 学习资料:
3. 思路
和上面那道题的三数之和思想一样,多了一个外层循环,并且剪枝和去重的操作,在第1和2层外层循环上稍有不同。
4. 代码
class Solution {
public List < List < Integer > > fourSum ( int [ ] nums, int target) {
List < List < Integer > > result = new ArrayList < > ( ) ;
Arrays . sort ( nums) ;
for ( int k = 0 ; k < nums. length; k++ ) {
if ( nums[ k] > target&& nums[ k] > 0 && target> 0 ) {
break ;
}
if ( k > 0 && nums[ k] == nums[ k- 1 ] ) {
continue ;
}
for ( int i = k + 1 ; i < nums. length; i++ ) {
if ( nums[ k] > 0 && nums[ i] > 0 && target > 0 && nums[ i] + nums[ k] > target) {
break ;
}
if ( i > k + 1 && nums[ i] == nums[ i- 1 ] ) {
continue ;
}
int left = i+ 1 ;
int right = nums. length - 1 ;
while ( left < right) {
long sum = ( long ) nums[ k] + nums[ i] + nums[ left] + nums[ right] ;
if ( sum > target) {
right-- ;
} else if ( sum < target) {
left++ ;
} else {
result. add ( Arrays . asList ( nums[ k] , nums[ i] , nums[ left] , nums[ right] ) ) ;
while ( left < right && nums[ right] == nums[ right- 1 ] ) {
right -- ;
}
while ( left < right && nums[ left] == nums[ left+ 1 ] ) {
left++ ;
}
left++ ;
right-- ;
}
}
}
}
return result;
}
}