Leetcode第254场周赛——题解及总结

1、作为子字符串出现在单词中的字符串数目

给你一个字符串数组 patterns 和一个字符串 word ,统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。
子字符串 是字符串中的一个连续字符序列。

示例 1:
输入:patterns = [“a”,“abc”,“bc”,“d”], word = “abc”
输出:3
解释:

  • “a” 是 “abc” 的子字符串。
  • “abc” 是 “abc” 的子字符串。
  • “bc” 是 “abc” 的子字符串。
  • “d” 不是 “abc” 的子字符串。
    patterns 中有 3 个字符串作为子字符串出现在 word 中。

1.1、解题思路及代码

直接python暴力就好了,python在处理字符串时有in函数就比较方便。

#官方解法
class Solution:
    def numOfStrings(self, patterns: List[str], word: str) -> int:
        return sum(1 if pattern in word else 0 for pattern in patterns)
#菜鸡写法
class Solution:
    def numOfStrings(self, patterns: List[str], word: str) -> int:
    	j=0
    	for i in patterns:
    		if(i in word):
    			j=j+1
    return j

2、构造元素不等于两相邻元素平均值的数组

给你一个 下标从 0 开始 的数组 nums ,数组由若干 互不相同的 整数组成。你打算重新排列数组中的元素以满足:重排后,数组中的每个元素都 不等于 其两侧相邻元素的 平均值 。
更公式化的说法是,重新排列的数组应当满足这一属性:对于范围 1 <= i < nums.length - 1 中的每个 i ,(nums[i-1] + nums[i+1]) / 2 不等于 nums[i] 均成立 。
返回满足题意的任一重排结果。

示例 1:
输入:nums = [1,2,3,4,5]
输出:[1,2,4,5,3]
解释:
i=1, nums[i] = 2, 两相邻元素平均值为 (1+4) / 2 = 2.5
i=2, nums[i] = 4, 两相邻元素平均值为 (2+5) / 2 = 3.5
i=3, nums[i] = 5, 两相邻元素平均值为 (4+3) / 2 = 3.5

2.1、解题思路和代码

方法一:

将数组排序分为两部分,奇数位放小的,偶数位放大的。

//c++写法
class Solution {
public:
    vector<int> rearrangeArray(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        vector<int> res;
        int m=(n+1)/2; 
        for(int i=0;i<m;++i)
        {
            res.push_back(nums[i]);
            if(i+m<n) res.push_back(nums[i+m]);
        }
        return res;
    }
};
//暴力随机写法,碰答案
class Solution {
public:
    vector<int> rearrangeArray(vector<int>& nums) {
        do shuffle(nums.begin(), nums.end(), mt19937(random_device()()));
        while(find_if(begin(nums) + 1, end(nums) - 1, [](int& x){return *prev(&x) + *next(&x) == x + x;}) != nums.end() - 1);
        return nums;
    }
};
//java双百写法
class Solution {
    public int[] rearrangeArray(int[] nums) {
        Arrays.sort(nums);
        int n=nums.length;
        int[] res=new int[n];
        int j=0;
        for(int i=0;i<n;i+=2) res[i]=nums[j++];
        for(int i=1;i<n;i+=2) res[i]=nums[j++];
        return res;
    }
}

3、数组元素的最小非零乘积

给你一个正整数 p 。你有一个下标从 1 开始的数组 nums ,这个数组包含范围 [1, 2p - 1] 内所有整数的二进制形式(两端都 包含)。你可以进行以下操作 任意 次:

1、 从 nums 中选择两个元素 x 和 y 。
2、选择 x 中的一位与 y 对应位置的位交换。对应位置指的是两个整数 相同位置 的二进制位。

比方说,如果 x = 1101 且 y = 0011 ,交换右边数起第 2 位后,我们得到 x = 1111 和 y = 0001 。
请你算出进行以上操作 任意次 以后,nums 能得到的 最小非零 乘积。将乘积对 109 + 7 取余 后返回。
注意:答案应为取余 之前 的最小值。

示例 1:
输入:p = 1
输出:1
解释:nums = [1] 。
只有一个元素,所以乘积为该元素。

解题思路和代码

仔细读题,它是可以选择性的交换位置,也就是说,001和110,可以只交换想要交换的位置,变成101和010,不一定全都要交换,所以和不变。在和不变的情况下,一个最小,一个最大就可以完成积最小,像10,1和9情况下积最小。这样的话,最后的 2 p − 1 2^{p}-1 2p1不参与(下标从1开始,最后一位不能和1进行交换的,因为会出现0的情况),所以就会有 2 p − 1 − 1 2^{p-1}-1 2p11 2 p − 2 2^{p}-2 2p2和1相乘(因为和是2^{p}-1)那么直接用式子表示为

( 2 p − 1 ) ∗ ( 2 p − 2 ) 2 p − 1 − 1 (2^p-1)*(2^p-2)^{2^{p-1}-1} (2p1)(2p2)2p11

class Solution:
    def minNonZeroProduct(self, p: int) -> int:
        return (2 ** p - 1) * pow(2 ** p - 2, 2 ** (p - 1) - 1, 10 ** 9 + 7) % (10 ** 9 + 7)

你可能感兴趣的:(刷题笔记,leetcode,字符串,算法)