leetcode 11~20
双指针
class Solution {
public :
int maxArea ( vector< int > & height) {
int ans = 0 , len = height. size ( ) ;
for ( int l = 0 , r = len - 1 ; l < r; ) {
ans = max ( ans, ( r - l) * min ( height[ l] , height[ r] ) ) ;
if ( height[ l] < height[ r] ) l++ ;
else r-- ;
}
return ans;
}
} ;
且记做数学吧,找规律
class Solution {
public :
string intToRoman ( int num) {
string res;
int values[ ] = {
1000 ,
900 , 500 , 400 , 100 ,
90 , 50 , 40 , 10 ,
9 , 5 , 4 , 1
} ;
string reps[ ] = {
"M" ,
"CM" , "D" , "CD" , "C" ,
"XC" , "L" , "XL" , "X" ,
"IX" , "V" , "IV" , "I"
} ;
for ( int i = 0 ; i < 13 ; i++ ) {
while ( num >= values[ i] ) {
num -= values[ i] ;
res += reps[ i] ;
}
}
return res;
}
} ;
数组模拟哈希表
class Solution {
public :
int romanToInt ( string s) {
int hash[ 26 ] = { 0 } , ans = 0 ;
hash[ 'I' - 'A' ] = 1 , hash[ 'V' - 'A' ] = 5 ;
hash[ 'X' - 'A' ] = 10 , hash[ 'L' - 'A' ] = 50 ;
hash[ 'C' - 'A' ] = 100 , hash[ 'D' - 'A' ] = 500 ;
hash[ 'M' - 'A' ] = 1000 ;
for ( int i = 0 ; i < s. length ( ) ; i++ ) {
if ( i < s. length ( ) - 1 && hash[ s[ i] - 'A' ] < hash[ s[ i + 1 ] - 'A' ] )
ans -= hash[ s[ i] - 'A' ] ;
else
ans += hash[ s[ i] - 'A' ] ;
}
return ans;
}
} ;
遍历就完事了
class Solution {
public :
string longestCommonPrefix ( vector< string> & strs) {
string res;
if ( strs. empty ( ) ) return res;
for ( int i = 0 ; ; i++ ) {
if ( i >= strs[ 0 ] . size ( ) ) return res;
char c = strs[ 0 ] [ i] ;
for ( auto & s : strs) {
if ( i >= s. size ( ) || s[ i] != c)
return res;
}
res += c;
}
return res;
}
} ;
排序后双指针,并且加了一些优化
class Solution {
public :
vector< vector< int >> threeSum ( vector< int > & nums) {
vector< vector< int >> ans;
sort ( nums. begin ( ) , nums. end ( ) ) ;
int len = nums. size ( ) ;
if ( len < 3 ) return ans;
for ( int i = 0 ; i < len; i ++ ) {
if ( i && nums[ i] == nums[ i - 1 ] ) continue ;
if ( nums[ i] > 0 ) break ;
for ( int j = i + 1 , k = len - 1 ; j < k; j++ ) {
if ( j - 1 > i && nums[ j - 1 ] == nums[ j] ) continue ;
if ( nums[ i] + nums[ j] > 0 ) break ;
while ( k - 1 > j && nums[ i] + nums[ j] + nums[ k - 1 ] >= 0 ) k-- ;
if ( nums[ i] + nums[ j] + nums[ k] == 0 )
ans. push_back ( { nums[ i] , nums[ j] , nums[ k] } ) ;
}
}
return ans;
}
} ;
双指针,看着像O(n^3),但第二个for之内j 和 k移动的次数和最大为n,故O(n^2)
class Solution {
public :
int threeSumClosest ( vector< int > & nums, int target) {
sort ( nums. begin ( ) , nums. end ( ) ) ;
int len = nums. size ( ) ;
pair< int , int > ans ( INT_MAX, INT_MAX) ;
for ( int i = 0 ; i < len; i++ ) {
for ( int j = i + 1 , k = len - 1 ; j < k; j ++ ) {
while ( k - 1 > j && nums[ i] + nums[ j] + nums[ k - 1 ] >= target) k-- ;
int t = nums[ i] + nums[ j] + nums[ k] ;
ans = min ( ans, make_pair ( abs ( t - target) , t) ) ;
if ( k - 1 > j) {
t = nums[ i] + nums[ j] + nums[ k - 1 ] ;
ans = min ( ans, make_pair ( target - t, t) ) ;
}
}
}
return ans. second;
}
} ;
或许是优化的解法,O(n^2)
class Solution {
public :
int threeSumClosest ( vector< int > & nums, int target) {
sort ( nums. begin ( ) , nums. end ( ) ) ;
const vector< int > :: size_type N = nums. size ( ) ;
if ( N >= 3 ) {
int sum = nums[ 0 ] + nums[ 1 ] + nums[ 2 ] ;
for ( auto x = nums. begin ( ) ; x < nums. end ( ) - 2 ; ++ x) {
auto left = x + 1 , right = nums. end ( ) - 1 ;
while ( left < right) {
const int t = * x + * left + * right;
if ( t > target) {
-- right;
if ( abs ( target - sum) > abs ( target - t) ) sum = t;
}
else if ( t < target) {
++ left;
if ( abs ( target - sum) > abs ( target - t) ) sum = t;
}
else return target;
}
}
return sum;
}
return 0 ;
}
} ;
DFS
class Solution {
public :
vector< string> ans;
string map[ 10 ] = {
"" , "" , "abc" , "def" ,
"ghi" , "jkl" , "mno" ,
"pqrs" , "tuv" , "wxyz"
} ;
vector< string> letterCombinations ( string digits) {
if ( digits. length ( ) == 0 ) return ans;
string temp;
dfs ( digits, 0 , temp) ;
return ans;
}
void dfs ( string digits, int i, string& temp) {
if ( i >= digits. length ( ) ) {
ans. push_back ( temp) ;
return ;
}
for ( int k = 0 ; k < map[ digits[ i] - '0' ] . length ( ) ; k++ ) {
temp += map[ digits[ i] - '0' ] [ k] ;
dfs ( digits, i + 1 , temp) ;
temp = temp. substr ( 0 , i) ;
}
}
} ;
y总的写法
vector< string> letterCombinations ( string digits) {
if ( digits. empty ( ) ) return ans;
dfs ( digits, 0 , "" ) ;
return ans;
}
void dfs ( string digits, int i, string path) {
if ( i >= digits. length ( ) ) {
ans. push_back ( path) ;
return ;
}
for ( auto c : map[ digits[ i] - '0' ] )
dfs ( digits, i + 1 , path + c) ;
}
遍历排序双指针,看着像O(n^4),但第三个for之内l 和 r移动的次数和最大为n,故O(n^3)
class Solution {
public :
vector< vector< int >> fourSum ( vector< int > & nums, int target) {
vector< vector< int >> ans;
int len = nums. size ( ) ;
sort ( nums. begin ( ) , nums. end ( ) ) ;
for ( int i = 0 ; i < len; i ++ ) {
if ( i && nums[ i] == nums[ i - 1 ] ) continue ;
for ( int j = i + 1 ; j < len; j ++ ) {
if ( j - 1 > i && nums[ j] == nums[ j - 1 ] ) continue ;
for ( int l = j + 1 , r = len - 1 ; l < r; l++ ) {
if ( l - 1 > j && nums[ l] == nums[ l - 1 ] ) continue ;
while ( r - 1 > l && ( ( long long ) nums[ i] + nums[ j] + nums[ l] + nums[ r - 1 ] ) >= target) r-- ;
if ( ( ( long long ) nums[ i] + nums[ j] + nums[ l] + nums[ r] ) == target)
ans. push_back ( { nums[ i] , nums[ j] , nums[ l] , nums[ r] } ) ;
}
}
}
return ans;
}
} ;
快慢指针,也可以先遍历求长度,复杂度是一样的
class Solution {
public :
ListNode* removeNthFromEnd ( ListNode* head, int n) {
auto dummy = new ListNode ( - 1 ) ;
dummy-> next = head;
auto left = dummy, right = head;
while ( n-- )
right = right-> next;
while ( right) {
left = left-> next;
right = right-> next;
}
left-> next = left-> next-> next;
return dummy-> next;
}
} ;
数组模拟栈
class Solution {
public :
char stack[ 5010 ] ;
bool isValid ( string s) {
int len = s. length ( ) ;
int top = - 1 ;
if ( len & 1 ) return false ;
for ( int i = 0 ; i < len; i++ ) {
if ( top >= len / 2 ) return false ;
if ( s[ i] == '(' || s[ i] == '[' || s[ i] == '{' )
stack[ ++ top] = s[ i] ;
else {
if ( s[ i] == ')' ) {
if ( top >= 0 && stack[ top] == '(' ) top-- ;
else return false ;
}
else if ( s[ i] == ']' ) {
if ( top >= 0 && stack[ top] == '[' ) top-- ;
else return false ;
}
else {
if ( top >= 0 && stack[ top] == '{' ) top-- ;
else return false ;
}
}
}
return top == - 1 ;
}
} ;
用stack模板,小技巧左括号与右括号asill码差小于等于2
class Solution {
public :
bool isValid ( string s) {
if ( s. length ( ) & 1 ) return false ;
stack< char > stk;
for ( auto c : s) {
if ( c == '[' || c == '(' || c == '{' )
stk. push ( c) ;
else if ( ! stk. empty ( ) && abs ( stk. top ( ) - c) <= 2 )
stk. pop ( ) ;
else return false ;
}
return stk. empty ( ) ;
}
} ;