题目描述
在第一人称射击游戏中,玩家通过键盘的A
、S
、D
、W
四个按键控制游戏人物分别向左、向后、向右、向前进行移动,从而完成走位。
假设玩家每按动一次键盘,游戏人物会向某个方向移动一步,如果玩家在操作一定次数的键盘并且各个方向的步数相同时,此时游戏人物必定会回到原点,则称此次走位为完美走位。
现给定玩家的走位(例如:ASDA
),请通过更换其中一段连续走位的方式使得原走位能够变成一个完美走位。
其中待更换的连续走位可以是相同长度的任何走位。
请返回待更换的连续走位的最小可能长度。
若果原走位本身是一个完美走位,则返回0
。
输入描述
输入为由键盘字母表示的走位s
,例如:ASDA
输出描述
输出为待更换的连续走位的最小可能长度
备注
- 走位长度 1≤s.length≤10^5
s.length
是4
的倍数s
中只含有A
,S
,D
,W
四种字符
示例一
输入
ASDW
输出
0
说明
已经是完美走位了。
示例二
输入
AASW
输出
1
说明
需要把一个A
更换成D
,这样可以得到ADSW
或者DASW
。
示例三
输入
AAAA
输出
3
说明
可以替换后 3
个 A
,得到ASDW
。
js
function perfectWalk(s) {
const n = s.length;
const cnt = { A: 0, S: 0, D: 0, W: 0 };
for (let i = 0; i < n; i++) {
cnt[s[i]]++;
}
const avg = n / 4;
if (cnt.A === avg && cnt.S === avg && cnt.D === avg && cnt.W === avg) {
return 0; // 已经是完美走位了
}
let ans = n; // 默认为走位的长度
for (let len = 1; len <= n / 4; len++) {
for (let i = 0; i + len <= n; i++) {
if ((i + len) % avg !== 0) {
continue; // 长度不为平均值的倍数,不是合法的替换方案
}
const cnt2 = { A: 0, S: 0, D: 0, W: 0 };
for (let j = i; j < i + len; j++) {
cnt2[s[j]]++;
}
if (cnt2.A === cnt2.S && cnt2.A === cnt2.D && cnt2.A === cnt2.W) {
ans = Math.min(ans, len);
}
}
}
return ans - avg; // 最小可能长度为 ans - avg
}
python
def perfectWalk(s):
n = len(s)
cnt = {'A': 0, 'S': 0, 'D': 0, 'W': 0}
for i in range(n):
cnt[s[i]] += 1
avg = n // 4
if cnt['A'] == avg and cnt['S'] == avg and cnt['D'] == avg and cnt['W'] == avg:
return 0 # 已经是完美走位了
ans = n # 默认为走位的长度
for length in range(1, n // 4 + 1):
for i in range(n - length + 1):
if (i + length) % avg != 0:
continue # 长度不为平均值的倍数,不是合法的替换方案
cnt2 = {'A': 0, 'S': 0, 'D': 0, 'W': 0}
for j in range(i, i + length):
cnt2[s[j]] += 1
if cnt2['A'] == cnt2['S'] == cnt2['D'] == cnt2['W']:
ans = min(ans, length)
return ans - avg # 最小可能长度为 ans - avg
java
public static int perfectWalk(String s) {
int n = s.length();
Map<Character, Integer> cnt = new HashMap<>();
cnt.put('A', 0);
cnt.put('S', 0);
cnt.put('D', 0);
cnt.put('W', 0);
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
cnt.put(c, cnt.get(c) + 1);
}
int avg = n / 4;
if (cnt.get('A') == avg && cnt.get('S') == avg && cnt.get('D') == avg && cnt.get('W') == avg) {
return 0; // 已经是完美走位了
}
int ans = n; // 默认为走位的长度
for (int len = 1; len <= n / 4; len++) {
for (int i = 0; i + len <= n; i++) {
if ((i + len) % avg != 0) {
continue; // 长度不为平均值的倍数,不是合法的替换方案
}
Map<Character, Integer> cnt2 = new HashMap<>();
cnt2.put('A', 0);
cnt2.put('S', 0);
cnt2.put('D', 0);
cnt2.put('W', 0);
for (int j = i; j < i + len; j++) {
char c = s.charAt(j);
cnt2.put(c, cnt2.get(c) + 1);
}
if (cnt2.get('A') == cnt2.get('S') && cnt2.get('A') == cnt2.get('D') && cnt2.get('A') == cnt2.get('W')) {
ans = Math.min(ans, len);
}
}
}
return ans - avg; // 最小可能长度为 ans - avg
}
c++
#include <string>
#include <unordered_map>
using namespace std;
int perfectWalk(string s) {
int n = s.length();
unordered_map<char, int> cnt;
cnt['A'] = 0;
cnt['S'] = 0;
cnt['D'] = 0;
cnt['W'] = 0;
for (int i = 0; i < n; i++) {
cnt[s[i]]++;
}
int avg = n / 4;
if (cnt['A'] == avg && cnt['S'] == avg && cnt['D'] == avg && cnt['W'] == avg) {
return 0; // 已经是完美走位了
}
int ans = n; // 默认为走位的长度
for (int len = 1; len <= n / 4; len++) {
for (int i = 0; i + len <= n; i++) {
if ((i + len) % avg != 0) {
continue; // 长度不为平均值的倍数,不是合法的替换方案
}
unordered_map<char, int> cnt2;
cnt2['A'] = 0;
cnt2['S'] = 0;
cnt2['D'] = 0;
cnt2['W'] = 0;
for (int j = i; j < i + len; j++) {
cnt2[s[j]]++;
}
if (cnt2['A'] == cnt2['S'] && cnt2['A'] == cnt2['D'] && cnt2['A'] == cnt2['W']) {
ans = min(ans, len);
}
}
}
return ans - avg; // 最小可能长度为 ans - avg
}