先用map记录前两个数的和num1 + num2
的值出现了多少次 再在后两个数组里找0 - (num1 + num2)
,找到后就累加map中的次数
class Solution {
public :
int fourSumCount ( vector< int > & nums1, vector< int > & nums2, vector< int > & nums3,
vector< int > & nums4) {
unordered_map< int , int > map;
for ( int num1 : nums1) {
for ( int num2 : nums2) {
map[ num1 + num2] ++ ;
}
}
int count = 0 ;
for ( int num3 : nums3) {
for ( int num4 : nums4) {
int need = 0 - ( num3 + num4) ;
if ( map. find ( need) != map. end ( ) ) {
count+= map[ need] ;
}
}
}
return count;
}
} ;
class Solution {
public :
bool canConstruct ( string ransomNote, string magazine) {
vector< int > arr ( 26 , 0 ) ;
for ( int i = 0 ; i < ransomNote. size ( ) ; i++ ) {
arr[ ransomNote[ i] - 'a' ] ++ ;
}
for ( int i = 0 ; i < magazine. size ( ) ; i++ ) {
arr[ magazine[ i] - 'a' ] -- ;
}
for ( int n : arr) {
if ( n > 0 ) {
return false ;
}
}
return true ;
}
} ;
首先对数组排序 定义三个指针,一个i
从0开始遍历数组,一个left
在i右边一位,一个right
在数组末尾 确定i
,不断移动left
和right
,同时要注意剪枝 nums[i] > 0
,第一个都大于0了,那后面不管怎样也不可能等于0i > 0 && nums[i] == nums[i - 1]
,重复元素就跳过,要找前一个元素,才是用过的元素找到三元数组收缩left
和right
时,也需要去重,用while
去找,找到第一个不相等的元素
class Solution {
public :
vector< vector< int >> threeSum ( vector< int > & nums) {
vector< vector< int >> ans;
sort ( nums. begin ( ) , nums. end ( ) ) ;
for ( int i = 0 ; i < nums. size ( ) ; i++ ) {
if ( nums[ i] > 0 ) {
return ans;
}
if ( i > 0 && nums[ i] == nums[ i - 1 ] ) {
continue ;
}
int left = i + 1 ;
int right = nums. size ( ) - 1 ;
while ( left < right) {
if ( nums[ i] + nums[ left] + nums[ right] > 0 ) {
right-- ;
} else if ( nums[ i] + nums[ left] + nums[ right] < 0 ) {
left++ ;
} else {
ans. push_back ( { nums[ left] , nums[ right] , nums[ i] } ) ;
while ( left < right && nums[ left] == nums[ left + 1 ] ) {
left++ ;
}
while ( left < right && nums[ right] == nums[ right - 1 ] ) {
right-- ;
}
left++ ;
right-- ;
}
}
}
return ans;
}
} ;
同上 注意是和target
做比较了 数据太大需要加一个(long)
class Solution {
public :
vector< vector< int >> fourSum ( vector< int > & nums, int target) {
vector< vector< int >> ans;
sort ( nums. begin ( ) , nums. end ( ) ) ;
for ( int i = 0 ; i < nums. size ( ) ; i++ ) {
if ( nums[ i] >= 0 && nums[ i] > target) {
return ans;
}
if ( i > 0 && nums[ i] == nums[ i - 1 ] ) {
continue ;
}
for ( int j = i + 1 ; j < nums. size ( ) ; j++ ) {
if ( nums[ i] + nums[ j] > target && nums[ i] + nums[ j] >= 0 ) {
break ;
}
if ( j > i + 1 && nums[ j] == nums[ j - 1 ] ) {
continue ;
}
int left = j + 1 ;
int right = nums. size ( ) - 1 ;
while ( left < right) {
if ( ( long ) nums[ i] + nums[ j] + nums[ left] + nums[ right] >
target) {
right-- ;
} else if ( ( long ) nums[ i] + nums[ j] + nums[ left] +
nums[ right] <
target) {
left++ ;
} else {
ans. push_back (
{ 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 ans;
}
} ;