1995 .统计特殊四元组(easy)
5864.游戏中的弱角色 (middle)
1997.访问完所有房间的第一天(middle)
1998.数组的最大公因数排序(hard)
5864. 游戏中弱角色的数量
你正在参加一个多角色游戏,每个角色都有两个主要属性:攻击 和 防御 。给你一个二维整数数组 properties
,其中 properties[i] = [attacki, defensei]
表示游戏中第 i
个角色的属性。
如果存在一个其他角色的攻击和防御等级 都严格高于 该角色的攻击和防御等级,则认为该角色为 弱角色 。更正式地,如果认为角色 i
弱于 存在的另一个角色 j
,那么 attackj > attacki
且 defensej > defensei
。
返回 弱角色 的数量。
示例 1:
输入:properties = [[5,5],[6,3],[3,6]]
输出:0
解释:不存在攻击和防御都严格高于其他角色的角色。
思路分析
- 题目涉及到数值比较,故先排序,排序顺序为攻击从大到小,同等攻击值从小到大。
- 弱角色存在于右边,在遍历过程中,右边角色攻击均小于或等于左边,设maxProperty为defense最大的非弱角色,de和at为其防御值和攻击值,这样可以保证在遍历过程中,右边所有弱角色防御和攻击均小于maxProperty。
- 遍历时maxProperty的更新条件如下:
i f P r o p e r t i e s [ i ] i s n o t a w e a k r o l e d e = P r o p e r t i e s [ i ] [ 1 ] a t = P r o p e r t i e s [ i ] [ 0 ] if \;Properties[i] \;is \;not \;a \;weak \;role\\ de = Properties[i][1]\\ at = Properties[i][0] ifProperties[i]isnotaweakrolede=Properties[i][1]at=Properties[i][0]
代码实现
int cmp(int **a,int **b){
if(a[0][0]!=b[0][0]){
return b[0][0]-a[0][0];
}
return a[0][1]-b[0][1];
}
int numberOfWeakCharacters(int** properties, int propertiesSize, int* propertiesColSize){
qsort(properties,propertiesSize,sizeof(properties[0]),cmp);
int at=properties[0][0];
int de=properties[0][1];
int count=0;
for (int i=1; i<propertiesSize; i++) {
if (de > properties[i][1]) {
if (at > properties[i][0]) {
count++;
}else{
de = properties[i][1];
at = properties[i][0];
}
} else {
de = properties[i][1];
at = properties[i][0];
}
}
return count;
}
运行效果
1997. 访问完所有房间的第一天
你需要访问 n
个房间,房间从 0
到 n - 1
编号。同时,每一天都有一个日期编号,从 0
开始,依天数递增。你每天都会访问一个房间。
最开始的第 0
天,你访问 0
号房间。给你一个长度为 n
且 下标从 0 开始 的数组 nextVisit
。在接下来的几天中,你访问房间的 次序 将根据下面的 规则 决定:
- 假设某一天,你访问
i
号房间。 - 如果算上本次访问,访问
i
号房间的次数为 奇数 ,那么 第二天 需要访问nextVisit[i]
所指定的房间,其中0 <= nextVisit[i] <= i
。 - 如果算上本次访问,访问
i
号房间的次数为 偶数 ,那么 第二天 需要访问(i + 1) mod n
号房间。
请返回你访问完所有房间的第一天的日期编号。题目数据保证总是存在这样的一天。由于答案可能很大,返回对 109 + 7
取余后的结果。
示例 1:
输入:nextVisit = [0,0]
输出:2
解释:
- 第 0 天,你访问房间 0 。访问 0 号房间的总次数为 1 ,次数为奇数。
下一天你需要访问房间的编号是 nextVisit[0] = 0
- 第 1 天,你访问房间 0 。访问 0 号房间的总次数为 2 ,次数为偶数。
下一天你需要访问房间的编号是 (0 + 1) mod 2 = 1
- 第 2 天,你访问房间 1 。这是你第一次完成访问所有房间的那天。
思路分析
-
动态规划,dp[i]表示从0房间到第i个房间所需要的时间。
-
根据0<=nextVisit[i]<=i可以判定访问次数为基数时必回退到小于等于i的某个点,为偶数时才会 +1,故从dp[i+1]=dp[i]+(dp[i]-dp[nextVisit[i]])+2
-
公式如下:
d p [ i ] = 2 ∗ d p [ i − 1 ] − d p [ n e x t V i s i t [ i − 1 ] ] + 2 dp[i] = 2*dp[i-1]-dp[nextVisit[i-1]]+2 dp[i]=2∗dp[i−1]−dp[nextVisit[i−1]]+2
代码
int firstDayBeenInAllRooms(int* nextVisit, int nextVisitSize){
long* dp = malloc(nextVisitSize*sizeof(long));
dp[0] = 0;
int mod = (int)1e9+7;
for(int i = 1;i<nextVisitSize;i++){
dp[i] = (2*dp[i-1]-dp[nextVisit[i-1]]+2+mod)%mod;
}
return (int)dp[nextVisitSize-1];
}
结果
1998.数组的最大公因数排序
给你一个整数数组 nums
,你可以在 nums
上执行下述操作 任意次 :
- 如果
gcd(nums[i], nums[j]) > 1
,交换nums[i]
和nums[j]
的位置。其中gcd(nums[i], nums[j])
是nums[i]
和nums[j]
的最大公因数。
如果能使用上述交换方式将 nums
按 非递减顺序 排列,返回 true
;否则,返回 false
。
示例 1:
输入:nums = [7,21,3]
输出:true
解释:可以执行下述操作完成对 [7,21,3] 的排序:
- 交换 7 和 21 因为 gcd(7,21) = 7 。nums = [21,7,3]
- 交换 21 和 3 因为 gcd(21,3) = 3 。nums = [3,7,21]
思路
-
拥有相同公因数的数可以相互交换位置,a与b可以交换,a与c可以交换,则a,b,c可以互相交换。
-
将所有可以相互交换位置的数字放入同一个集合中,以链式结构存放,若两个数可以相互交换,则a的链尾等于b的链尾。
-
nums[i]<=105,故用长度为105+1的数组p作为链接数组,p[i]表示i的下一个节点。
-
将原数组排序,比较新数组与原数组nums[i]与nums[i]是否可以进行交换,若不能交换则返回false.
代码
//找到尾部节点并更新前面节点指向的节点
int find(int x,int* p){
if(x!=p[x]){
p[x]=find(p[x],p);
}
return p[x];
}
//合并,将新数添加到之前的集合中
void merge(int x,int y,int* p){
int a = find(x,p);
int b = find(y,p);
if(a==b){
return;
}
p[a]=b;
}
int cmp(int* a,int* b){
return *a-*b;
}
bool gcdSort(int* nums, int numsSize){
int N = 1e5+1;
int* p=malloc(N*sizeof(int));
for(int i=0;i<N;i++){
p[i]=i;
}
//分解质因数
for(int i=0;i<numsSize;i++){
int k = nums[i];
for(int j=2;j<=k/j;j++){
bool flag = false;
while(k%j==0){
k=k/j;
flag=true;
}
if(flag){
merge(nums[i],j,p);
}
}
if(k>1){
merge(nums[i],k,p);
}
}
//tmp数组存储原来的数据
int* tmp = malloc(numsSize*sizeof(int));
for(int i=0;i<numsSize;i++){
tmp[i]=nums[i];
}
//排序
qsort(nums,numsSize,sizeof(int),cmp);
for(int i=0;i<numsSize;i++){
if(nums[i] == tmp[i]){
continue;
}
if(find(nums[i],p) != find(tmp[i],p)){
return false;
}
}
return true;
}
结果