【无标题】

第二题轻轻松松嘿嘿嘿
新的周赛只写了一道题,太惨了,记录在下面
第 77 场双周赛,用了一个多小时写出来两道题,算法能力还需要加强www,明天参加完周赛再来更新,睡了睡了晚安

  1. 统计是给定字符串前缀的字符串数目
    给你一个字符串数组 words 和一个字符串 s ,其中 words[i] 和 s 只包含 小写英文字母 。请你返回 words 中是字符串 s 前缀 的 字符串数目 。
    一个字符串的 前缀 是出现在字符串开头的子字符串。子字符串 是一个字符串中的连续一段字符序列。
输入:words = ["a","b","c","ab","bc","abc"], s = "abc"
输出:3
解释:
words 中是 s = "abc" 前缀的字符串为:
"a" ,"ab" 和 "abc" 。
所以 words 中是字符串 s 前缀的字符串数目为 3 。

思路:暴力遍历

class Solution {
    public int countPrefixes(String[] words, String s) {
        int sum = 0;
        for(String word : words) {
            int flag = 1;
            if (word.length() > s.length()) continue;
            for(int i = 0; i < word.length(); ++i) {
                
                if(word.charAt(i) != s.charAt(i)) flag = 0;
            }
            if(flag == 1) sum += 1;
        }
        return sum;
    }
}
  1. 最小平均差
    给你一个下标从 0 开始长度为 n 的整数数组 nums 。下标 i 处的 平均差 指的是 nums 中 前 i + 1 个元素平均值和 后 n - i - 1 个元素平均值的 绝对差 。两个平均值都需要 向下取整 到最近的整数。请你返回产生 最小平均差 的下标。如果有多个下标最小平均差相等,请你返回 最小 的一个下标。
    注意:

    两个数的 绝对差 是两者差的绝对值。
    n 个元素的平均值是 n 个元素之 和 除以(整数除法) n 。
    0 个元素的平均值视为 0 。

输入:nums = [2,5,3,9,5,3]
输出:3
解释:
- 下标 0 处的平均差为:|2 / 1 - (5 + 3 + 9 + 5 + 3) / 5| = |2 / 1 - 25 / 5| = |2 - 5| = 3 。
- 下标 1 处的平均差为:|(2 + 5) / 2 - (3 + 9 + 5 + 3) / 4| = |7 / 2 - 20 / 4| = |3 - 5| = 2 。
- 下标 2 处的平均差为:|(2 + 5 + 3) / 3 - (9 + 5 + 3) / 3| = |10 / 3 - 17 / 3| = |3 - 5| = 2 。
- 下标 3 处的平均差为:|(2 + 5 + 3 + 9) / 4 - (5 + 3) / 2| = |19 / 4 - 8 / 2| = |4 - 4| = 0 。 
- 下标 4 处的平均差为:|(2 + 5 + 3 + 9 + 5) / 5 - 3 / 1| = |24 / 5 - 3 / 1| = |4 - 3| = 1 。
- 下标 5 处的平均差为:|(2 + 5 + 3 + 9 + 5 + 3) / 6 - 0| = |27 / 6 - 0| = |4 - 0| = 4 。
下标 3 处的平均差为最小平均差,所以返回 3 。

思路:一开始就想到前缀和,但是没理解前缀和的精髓,去化简公式了,化简之后发现两个平均值要单独取整,所以最后还是按照原公式做,加上一个数组来记录前缀和;另外注意用long类型防止溢出。

class Solution {
    public int minimumAverageDifference(int[] nums) {
        int n = nums.length;
        long[] sum = new long[n + 1];
        for(int i = 0; i < n; ++i) {
            sum[i + 1] = sum[i] + nums[i];
        }
        
        int minn = Integer.MAX_VALUE, result = 0;
        
        for(int i = 0; i < n; ++i) {
            int chu = 0;
            if(i == n - 1) chu = 0;
            else chu = (int)((sum[n] - sum[i+1]) / (n - i - 1));
            int res = Math.abs((int)(sum[i+1] / (i + 1)) - chu);
            if (res < minn) {
                minn = res;
                result = i;
            }
        }
        return result;
    }
}
  1. 移除指定数字得到的最大结果 显示英文描述
    给你一个表示某个正整数的字符串 number 和一个字符 digit 。从 number 中 恰好 移除 一个 等于 digit 的字符后,找出并返回按 十进制 表示 最大 的结果字符串。生成的测试用例满足 digit 在 number 中出现至少一次。
输入:number = "1231", digit = "1"
输出:"231"
解释:可以移除第一个 '1' 得到 "231" 或者移除第二个 '1' 得到 "123" 。
由于 231 > 123 ,返回 "231" 。

思路:如果直接用数字做,有测试用例非常非常大,比如“3583799376562395845793479237239465237598237459573929667”这样,已经完全超过了数据类型的范围,而且看题目的输入输出都是字符串,所以很明显要从字符串中找规律。
我的思路是比较简单的,假设字符串中ch与digit相等,那么会出现两种,第一种类似于7678,ch后面有大于ch字符的,如果删掉的话后面的字符串就会前移,那么从前往后遍历找第一个s(i+1)>ch的,一定是最大的;第二种,所有的ch后一位都小于ch,例如9897,从后往前遍历找第一个ch。

class Solution {
    public String removeDigit(String number, char digit) {
        int len = number.length();
        int flag = 1;
        for(int i = 0; i < len; ++i) {
            char ch = number.charAt(i);
            if(ch == digit) {
                if(i == len - 1) return number.substring(0, i);
                if(number.charAt(i + 1) > ch) {
                    flag = 0;
                    return number.substring(0, i) + number.substring(i + 1, len);
                }        
            }
        }
        if (flag == 1) {
            for(int i = len - 1; i >= 0; --i) {
            char ch = number.charAt(i);
            if(ch == digit) {
                    return number.substring(0, i) + number.substring(i + 1, len);
                }        
            }
        }
        return " ";
    }
}
  1. 必须拿起的最小连续卡牌数
    给你一个整数数组 cards ,其中 cards[i] 表示第 i 张卡牌的 值 。如果两张卡牌的值相同,则认为这一对卡牌 匹配 。返回你必须拿起的最小连续卡牌数,以使在拿起的卡牌中有一对匹配的卡牌。如果无法得到一对匹配的卡牌,返回 -1 。
输入:cards = [3,4,2,3,4,7]
输出:4
解释:拿起卡牌 [3,4,2,3] 将会包含一对值为 3 的匹配卡牌。注意,拿起 [4,2,3,4] 也是最优方案。

思路:把每个元素以及出现的下标存到map里,然后遍历map.values()

class Solution {
    public int minimumCardPickup(int[] cards) {
        Map<Integer, List<Integer>> map = new HashMap<>();
        for(int i = 0; i < cards.length; ++i) {
            if(!map.containsKey(cards[i])) {
                List<Integer> myList = new ArrayList<Integer>();
                myList.add(i);
                map.put(cards[i],myList);
            } else {
                map.get(cards[i]).add(i);
            }
        }
        int min = 100000;
        for(List list : map.values()) {
            if (list.size() == 1) continue;
            for(int i = 0; i < list.size() - 1; ++i) {
                int res = (int)list.get(i + 1) - (int)list.get(i);
                if (res < min) min = res;
            }
        }
        if(min == 100000) return  - 1;      
        else return min + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值