二分查找
lc704
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;
}
} ;