移除字母异位词后的结果数组
思路分析
先给每个字符串排序,然后如果当前的字符串和前一个字符串不相等,那么这个就放到最后的答案里面。
代码
class Solution {
public :
vector< string> removeAnagrams ( vector< string> & words) {
vector< string> ans;
int n= words. size ( ) ;
string now= "" ;
for ( auto x: words) {
string tmp= x;
sort ( x. begin ( ) , x. end ( ) ) ;
if ( x!= now) {
now= x;
ans. push_back ( tmp) ;
}
}
return ans;
}
} ;
不含特殊楼层的最大连续楼层数
思路分析
先对所有的特殊的楼层进行排序,然后我们求在
[
b
o
t
t
o
m
,
t
o
p
]
[bottom,top]
[ b o t t o m , t o p ] 之间的特殊楼层之间的距离的最大值就行了。这里我们将在区间左侧的,也就是比区间小的移到bottom-1,将区间右侧,比区间大的移到top+1,最后对数组排序,找到相邻位置之间的最大距离就行了。
代码
class Solution {
public :
int maxConsecutive ( int b, int t, vector< int > & a) {
a. push_back ( b- 1 ) ;
a. push_back ( t+ 1 ) ;
sort ( a. begin ( ) , a. end ( ) ) ;
int ans= 0 ;
int l= b;
for ( auto x: a) {
if ( x< b) x= b- 1 ;
if ( x> t) x= t+ 1 ;
}
int n= a. size ( ) ;
for ( int i= 1 ; i< n; i++ ) {
ans= max ( ans, a[ i] - a[ i- 1 ] - 1 ) ;
}
return ans;
}
} ;
按位与结果大于零的最长组合
思路分析
对于每个数字,我们用二进制的眼光看待,我们发现,如果想要不为0,只需有一位对于所有的数,这一位都不是0就行了。也就是我们需要找出每一位的0有多少个,如果想要最后的数尽可能多,就需要找到最少0的那一位。有多少个数在这一位是0,然后将这些数去掉就行了。最后剩下的就是最多的数。
代码
class Solution {
public :
int x[ 30 ] ;
int largestCombination ( vector< int > & a) {
memset ( x, 0 , sizeof ( x) ) ;
for ( auto c: a) {
for ( int i= 0 ; i< 30 ; i++ ) {
if ( ( c>> i) & 1 ) {
continue ;
} else {
x[ i] ++ ;
}
}
}
int ans= 1e9 ;
for ( int i= 0 ; i< 30 ; i++ ) {
ans= min ( ans, x[ i] ) ;
}
ans= a. size ( ) - ans;
return ans;
}
} ;
统计区间中的整数数目
思路分析
这个题目其实挺难的,对于非竞赛选手可能有点吃力。比赛的时候一直想的是树状数组,区间修改,区间查询,但是数据范围很大,显然是不行的。但是,我们又思考,如果使用的是线段树,这个查询其实就是询问的根结点的 情况。我们只需要O(1)就可以查出来,主要的麻烦点是更新的操作。由于这个的区间长度很大,我们不可能开这么大的数组来处理,但是我们发现询问的次数是有限的,所以我们采用动态开点的方法来进行处理。如果有必要创建一个新的Node,我们才创建这个Node。这样就可以很好地控制空间地使用率了。
代码
class CountIntervals {
public :
int lazy;
int l, r;
int sum= 0 ;
CountIntervals* leftNode= NULL ;
CountIntervals* rightNode= NULL ;
CountIntervals ( ) {
l= 1 , r= 1e9 ;
}
CountIntervals ( int _l, int _r) {
l= _l; r= _r;
}
void add ( int left, int right) {
if ( sum== r- l+ 1 ) {
return ;
}
if ( l>= left&& r<= right) {
sum= r- l+ 1 ;
return ;
}
int mid= ( l+ r) >> 1 ;
if ( leftNode== NULL ) leftNode= new CountIntervals ( l, mid) ;
if ( rightNode== NULL ) rightNode= new CountIntervals ( mid+ 1 , r) ;
if ( left<= mid) {
leftNode-> add ( left, right) ;
}
if ( right> mid) {
rightNode-> add ( left, right) ;
}
sum= leftNode-> sum+ rightNode-> sum;
}
int count ( ) {
return sum;
}
} ;