二分查找
lc704
题目lc704 回忆y总的两个二分套路:acwing 代码如下:
class Solution {
public: int search ( vector< int > & nums, int target) { int left = 0 , right = nums. size ( ) - 1 ; while ( left < right) { int mid = ( left + right) >> 1 ; if ( nums[ mid] >= target) { right = mid; } else { left = mid + 1 ; } } if ( nums[ left] == target) { return left; } return - 1 ; }
} ;
lc35
class Solution {
public: int searchInsert ( vector< int > & nums, int target) { int left = 0 , right = nums. size ( ) ; while ( left < right) { int mid = ( left + right) >> 1 ; if ( nums[ mid] >= target) { right = mid; } else { left = mid + 1 ; } } return left; }
} ;
lc34
class Solution {
public: vector< int > searchRange ( vector< int > & nums, int target) { if ( nums. empty ( ) ) { return { - 1 , - 1 } ; } int left = 0 , right = nums. size ( ) - 1 ; while ( left < right) { int mid = left + ( right - left) / 2 ; if ( nums[ mid] >= target) { right = mid; } else { left = mid + 1 ; } } if ( nums[ left] != target) { return { - 1 , - 1 } ; } int first = left; left = 0 , right = nums. size ( ) - 1 ; while ( left < right) { int mid = left + ( right - left + 1 ) / 2 ; if ( nums[ mid] <= target) { left = mid; } else { right = mid - 1 ; } } return { first, left} ; }
} ;
lc69
lc69 回忆浮点数二分:保证一定精度内正确;但这题使用整数二分即可 代码
class Solution {
public: int mySqrt ( int x) { int left = 0 , right = 1e9 ; while ( left < right) { int mid = ( right + left + 1 ) / 2 ; if ( ( long long ) mid * mid <= x) { left = mid; } else { right = mid - 1 ; } } return left; }
} ;
lc367
class Solution {
public: bool isPerfectSquare ( int num) { int left = 1 , right = 1e9 ; while ( left < right) { int mid = ( left + right) >> 1 ; if ( ( long long ) mid * mid >= num) { right = mid; } else { left = mid + 1 ; } } if ( ( long long ) left * left == num) { return true; } return false; }
} ;
快慢指针
lc27
lc27 暴力解:双重for,遍历到val就全部元素往前移一个位置,时间复杂度为O(n^2) 优化思路:弄懂快慢指针含义即可,时间复杂度为O(n) fast: 原数组位置,寻找不为val值的元素 slow:最终的目标数组位置 变化:fast指向的不是val的元素放到slow处 代码
class Solution {
public: int removeElement ( vector< int > & nums, int val) { int fast = 0 , slow = 0 ; for ( ; fast < nums. size ( ) ; fast++ ) { if ( val != nums[ fast] ) { nums[ slow++ ] = nums[ fast] ; } } return slow; }
} ;
lc26
题目 上一题的变形,主要理解快慢指针的含义和他们之间的关系 代码
class Solution {
public: int removeDuplicates ( vector< int > & nums) { if ( nums. empty ( ) ) { return 0 ; } int slow = 1 , fast = 1 ; for ( ; fast < nums. size ( ) ; fast++ ) { if ( nums[ fast] != nums[ fast - 1 ] ) { nums[ slow++ ] = nums[ fast] ; } } return slow; }
} ;
lc844
lc844 思路1:利用上面快慢指针的思想,分别得到两个最终的字符串后,再比较,时间复杂度为O(n+m);也可以用栈的思路获取最终的字符串 代码:
class Solution {
public: bool backspaceCompare ( string s, string t) { int change_s = changeString ( s) ; int change_t = changeString ( t) ; cout << "s = " << s << " t = " << t << endl; cout << change_s << ' ' << change_t << endl; if ( change_s != change_t ) { return false; } for ( int i = 0 ; i < change_s; i++ ) { if ( s[ i] != t[ i] ) { return false; } } return true; } int changeString ( string & str) { int slow = 0 , fast = 0 ; for ( ; fast < str. size ( ) ; fast++ ) { if ( str[ fast] == '#' ) { if ( slow != 0 ) { -- slow; } } else { str[ slow++ ] = str[ fast] ; } } return slow; }
} ;
lc977
lc977 思路:相向指针,因为负数平方从大到小,正数平方从小到大;两个指针比较即两个数的平方比较,大的一个放到目标数组中 代码
class Solution {
public: vector< int > sortedSquares ( vector< int > & nums) { int n_size = nums. size ( ) - 1 ; vector< int > ret ( n_size + 1 ) ; for ( int i = 0 , j = n_size, pos = n_size; i <= j; ) { if ( nums[ i] * nums[ i] <= nums[ j] * nums[ j] ) { ret[ pos-- ] = nums[ j] * nums[ j] ; j-- ; } else { ret[ pos-- ] = nums[ i] * nums[ i] ; i++ ; } } return ret; }
} ;