微软笔试8.26,附上题目和自己的解法,求大伙帮找下缺漏

Task1

  • 题目

图片说明

  • 思路
    对撞指针。用一个数组来统计字符串中每个字母出现的次数,如果数组中每个元素出现的次数都为偶数,则代表该字符串符合题目要求。左右指针对撞,如果当前l和r所指的字符的出现次数都为偶数,则判断当前子串是否符合要求,符合则返回当前字符串长度;不符合,左右指针都向中间靠拢一步,对应的字符出现次数数组中的值减一;如果l和r所指字符出现次数都为奇数,则判断是否所指字符是否相等,如果相等则移动任意一个指针,对应次数减一;如果不相等,左右都移动然后次数减一
  • code
//对撞指针
    public int task1(String S) {
        int l = 0, r = S.length() - 1;
        int[] count = new int[26];
        for (int i = 0; i < S.length(); i++) {
            count[S.charAt(i) - 'a']++;
        }
        while (l < r) {
            if (count[S.charAt(l) - 'a'] % 2 == 0 && count[S.charAt(r) - 'a'] % 2 == 0 && isOk(count))
                return r - l + 1;

            if (S.charAt(l) == S.charAt(r) && count[S.charAt(l) - 'a'] % 2 != 0) {
                count[S.charAt(l) - 'a']--;
                l++;
            } else if (count[S.charAt(l) - 'a'] % 2 == 0 && count[S.charAt(r) - 'a'] % 2 == 0 && !isOk(count) ||
                    count[S.charAt(l) - 'a'] % 2 != 0 && count[S.charAt(r) - 'a'] % 2 != 0
            ) {
                count[S.charAt(l) - 'a']--;
                count[S.charAt(r) - 'a']--;
                l++;
                r--;
            } else if (count[S.charAt(l) - 'a'] % 2 != 0) {
                count[S.charAt(l) - 'a']--;
                l++;
            } else {
                count[S.charAt(r) - 'a']--;
                r--;
            }
        }
        return 0;
    }

    private boolean isOk(int[] count) {
        for (int j : count) {
            if (j % 2 == 1)
                return false;
        }
        return true;
    }

Task2

  • 题目

图片说明

  • 思路
    用一个map来存储坐标对应的点的集合,然后遍历数组,判断map中是否含有A[i] + k * M (k=1,2,3...,A[i] + k * M <= 坐标最大值)的点,如果有就将这些点全部放在一个集合里面,记录集合的最大长度,即为所求

  • code

public int task2(int[] A, int M) {
        //坐标为k的点的集合
        HashMap<Integer, HashSet<Integer>> map = new HashMap<>();
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < A.length; i++) {
            HashSet<Integer> set = map.getOrDefault(A[i], new HashSet<>());
            set.add(i);
            map.put(A[i], set);
            max = Math.max(max, A[i]);
        }
        int ans = 1;
        for (int i = 0; i < A.length; i++) {
            HashSet<Integer> set = new HashSet<>();
            for (int x = A[i] + M; x <= max; x = x + M) {
                if (map.containsKey(x)) {
                    //取并集
                    set.addAll(map.get(A[i]));
                    set.addAll(map.get(x));
                }
            }
            ans = Math.max(set.size(), ans);
        }
        return ans;
    }

Task3

  • 题目

图片说明

  • 思路
    就是求A和B merge后的最小未出现的正数,不算太难,这里用list来存C

  • code

    public int task3(int[] A, int[] B) {
          LinkedList<Integer> list = new LinkedList<>();
          for (int i = 0; i < A.length; i++) {
              list.add(Math.max(A[i], B[i]));
          }
          int ans = Integer.MAX_VALUE;
          for (int x : A) {
              if (!list.contains(x))
                  ans = Math.min(x, ans);
          }
          for (int x : B) {
              if (!list.contains(x))
                  ans = Math.min(x, ans);
          }
          for (int i = 1; i <= ans; i++) {
              if (!list.contains(i)) {
                  ans = i;
                  break;
              }
          }
          return ans;
      }

总结

我认为解法中还有很多缺漏,虽然每道题样例都过了,但是应该都不完全对,欢迎大伙有更好的思路和解法分享

#微软笔试#
全部评论
微软笔试是不是没开摄像头啊
1 回复 分享
发布于 2022-08-27 11:25 重庆
第一题可以用类似前缀和+位运算异或+哈希表的思路。第二题可以直接取余,注意负数就行。第三题我感觉自己不一定对。
1 回复 分享
发布于 2022-08-27 08:37 上海

相关推荐

点赞 评论 收藏
分享
1 3 评论
分享
牛客网
牛客企业服务