一、两数之和的扩展
class Solution { public List < List < Integer > > threeSum ( int [ ] nums) { Set < List < Integer > > set = new HashSet < > ( ) ; for ( int i= 0 ; i< nums. length; i++ ) { Map < Integer , Integer > map = new HashMap < > ( ) ; for ( int j= i+ 1 ; j< nums. length; j++ ) { int complement = - nums[ i] - nums[ j] ; if ( map. containsKey ( complement) ) { Integer [ ] tmp = new Integer [ ] { nums[ i] , nums[ j] , complement} ; Arrays . sort ( tmp) ; set. add ( Arrays . asList ( tmp) ) ; } map. put ( nums[ j] , j) ; } } return new ArrayList < > ( set) ; }
}
注意:
关于数组的操作在Arrays
(注意有s)中,例如:排序Arrays.sort(tmp)
->tmp直接变,无需返回值 数组与集合相互转换:Arrays.asList()
(数组->list) list.toArray()
(list->数组) 集合与集合相互转换:new ArrayList<>(set)
(set->list) new HashSet<>(list)
(list->set)
错误原因:超出时间限制
双指针解法:先用一个 for 循环遍历数组,对于每个数字,使用双指针在数组的剩余部分查找和为 0 的另外两个元素。
class Solution { public List < List < Integer > > threeSum ( int [ ] nums) { List < List < Integer > > res = new LinkedList < > ( ) ; Arrays . sort ( nums) ; for ( int i= 0 ; i< nums. length- 2 ; i++ ) { int left= i+ 1 , right= nums. length- 1 , complement= - nums[ i] ; if ( i== 0 || i> 0 && nums[ i] != nums[ i- 1 ] ) { while ( left< right) { if ( complement == nums[ right] + nums[ left] ) { Integer [ ] tmp= new Integer [ ] { nums[ i] , nums[ right] , nums[ left] } ; res. add ( Arrays . asList ( tmp) ) ; while ( left< right && nums[ left] == nums[ left+ 1 ] ) { left++ ; } while ( left< right && nums[ right] == nums[ right- 1 ] ) { right-- ; } left++ ; right-- ; } else if ( complement > nums[ right] + nums[ left] ) { left++ ; } else { right-- ; } } } } return res; }
}
注意:
LinkedList
中有ed
;不存在HashlList
在if(complement == nums[right]+nums[left])
判断后,还要判断if(complement > nums[right]+nums[left])
,确保后面有 在for
内还有while
循环,用于循环后面两个数 Arrays.asList(1,2,3);
or Integer[] tmp = new Integer[]{1,2,3}; Arrays.asList(tmp);