---
cid: 127
title: 周赛158
slug: 127
date: 2019/10/13 15:23:00
updated: 2019/11/04 07:57:52
status: publish
author: harumonia
categories:
  - 源流清泉
  - leetcodeの解题日志
tags:
noThumbInfoStyle: default
outdatedNotice: no
reprint: standard
thumbChoice: default
thumbStyle: default
hidden: false
---

## 分割平衡字符串

### 题目

[传送门](https://leetcode-cn.com/problems/split-a-string-in-balanced-strings/)

> 在一个「平衡字符串」中，'L' 和 'R' 字符的数量是相同的。
> 给出一个平衡字符串 s，请你将它分割成尽可能多的平衡字符串。
> 返回可以通过分割得到的平衡字符串的最大数量。

### 分析

典型的栈思路。
不过本体只取思路，不用结构。因为完全可以省下这部分的空间消耗。

### 代码

```c++
class Solution {
public:
    int balancedStringSplit(string s) {
        int n = s.length(),count = 0,res = 0;
        for(int i = 0; i< n; i++){
            if(s[i] == s[0]) count++;
            else count--;
            if(count == 0) res++;
        }
        return res;
    }
};
```

时间消耗:O(n)
空间消耗:O(1)

## 可以攻击国王的皇后

### 题目1

[传送门](https://leetcode-cn.com/problems/queens-that-can-attack-the-king/)

> 在一个 8x8 的棋盘上，放置着若干「黑皇后」和一个「白国王」。
>
> 「黑皇后」在棋盘上的位置分布用整数坐标数组 queens 表示，「白国王」的坐标用数组 king 表示。
>
> 「黑皇后」的行棋规定是：横、直、斜都可以走，步数不受限制，但是，不能越子行棋。
>
> 请你返回可以直接攻击到「白国王」的所有「黑皇后」的坐标（任意顺序）。

### 分析1

构建稀疏矩阵，然后从国王的位置向 8 个方向查找，找到即停止。
一个值得注意的地方是，矩阵的边界应该由 queens 和 king 共同决定。
存在数学解法。

### 代码1

```c++
class Solution {
public:
    vector<vector<int>> queensAttacktheKing(vector<vector<int>>& queens, vector<int>& king) {
        int m = 0, n = 0;
        for(auto i:queens){
            if(m < i[0]) m = i[0];
            if(n < i[1]) n = i[1];
        }
        if(m < king[0]) m = king[0];
        if(n < king[1]) n = king[1];
        m++;
        n++;
        vector<vector<int>> tmp(m,vector<int>(n,0)) , res;
        for(auto i:queens)
            tmp[i[0]][i[1]] = 1;

        int i = king[0],j = king[1];
        while(i>0 && i<m)
            if(tmp[--i][j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(i>=0 && i<m-1)
            if(tmp[++i][j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(j>0 && j<n)
            if(tmp[i][--j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(j>=0 && j<n-1)
            if(tmp[i][++j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(i>0 && i<m && j>0 && j<n)
            if(tmp[--i][--j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(i>=0 && i<m-1 && j>=0 && j<n-1)
            if(tmp[++i][++j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(i>0 && i<m && j>=0 && j<n-1)
            if(tmp[--i][++j] == 1){
                res.push_back({i,j});
                break;
            }

        i = king[0],j = king[1];
        while(i>=0 && i<m-1 && j>0 && j<n)
            if(tmp[++i][--j] == 1){
                res.push_back({i,j});
                break;
            }

        return res;
    }
};
```

## 最大相等频率

### 题目2

[传送门](https://leetcode-cn.com/problems/maximum-equal-frequency/)

> 给出一个正整数数组 nums，请你帮忙从该数组中找出能满足下面要求的 最长 前缀，并返回其长度：
> 从前缀中 删除一个 元素后，使得所剩下的每个数字的出现次数相同。
> 如果删除这个元素后没有剩余元素存在，仍可认为每个数字都具有相同的出现次数（也就是 0 次）。

### 分析2

构建双哈希表，第一张表存放每个元素出现的次数，第二张表存放每个次数(第一张表的元素)出现的次数。

### 代码2

```c++
class Solution {
public:
    int maxEqualFreq(vector<int>& nums) {
        map<int,int> ma;
        int n = nums.size();
        for(int i = 0;i < n;i++)
            ma[nums[i]]++;
        if(ma.size() == 1) return n;
        for(int i = n-1 ; i >=0 ; i--){
            map<int,int> matmp;
            for(const auto& m:ma)
                matmp[m.second]++;
            std::map<int,int>::iterator iter=matmp.begin();
            for (iter;iter!=matmp.end();){
                if (iter->first==0)
                    matmp.erase(iter++);
                else
                    iter++;
            }
            ma[nums[i]]--;
            if(i == n-1 && matmp.size() == 1 && ma[nums[0]] == 1) return n;
            if(matmp.size() != 2) continue;
            vector<int> vec1,vec2;
            for(const auto& m:matmp){
                vec1.push_back(m.first);
                vec2.push_back(m.second);
            }
            int min = vec1[0] > vec1[1] ? 0 : 1;
            if((vec2[min] == 1 && abs(vec1[0]-vec1[1]) == 1) || (vec1[0] == 1 && vec2[0] == 1)) return i+1;
        }
        return 0;
    }
};
```

## 后记

又是快要饿死的一天。
