华为OD机试真题 完美走位 JavaScript java python c++ 参考解题

题目描述

在第一人称射击游戏中,玩家通过键盘的ASDW四个按键控制游戏人物分别向左、向后、向右、向前进行移动,从而完成走位。
假设玩家每按动一次键盘,游戏人物会向某个方向移动一步,如果玩家在操作一定次数的键盘并且各个方向的步数相同时,此时游戏人物必定会回到原点,则称此次走位为完美走位。
现给定玩家的走位(例如:ASDA),请通过更换其中一段连续走位的方式使得原走位能够变成一个完美走位。
其中待更换的连续走位可以是相同长度的任何走位。
请返回待更换的连续走位的最小可能长度。
若果原走位本身是一个完美走位,则返回0

输入描述

输入为由键盘字母表示的走位s,例如:ASDA

输出描述

输出为待更换的连续走位的最小可能长度

备注

  1. 走位长度 1≤s.length≤10^5
  2. s.length 是 4 的倍数
  3. s 中只含有 ASDW 四种字符

示例一

输入

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
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值