0
点赞
收藏
分享

微信扫一扫

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:SwipeGesture)

有点d伤 03-11 18:30 阅读 2

目录

1. 长度最小的数组

class Solution 
{
public:
    int minSubArrayLen(int target, vector<int>& nums)
    {
        int sum = 0;
        int len = 0;
        int right = -1;
        int left = -1;
        int size = nums.size();
        while (right < size)
        {
            if (sum < target)
            {
                ++right;
                if (right < nums.size())
                {
                    sum += nums[right];
                }
            }
            else
            {
                if (len == 0 || len > right - left)
                {
                    len = right - left;
                }
                ++left;
                sum -= nums[left];
            }
        }

        return len;
    }
};
class Solution 
{
public:
    int minSubArrayLen(int target, vector<int>& nums) 
    {
        int count = INT_MAX;
        int sum = 0;
        for(int right = 0, left = 0; right < nums.size(); right++)
        {
            sum += nums[right];

            while(target <= sum)
            {
                if(count > right - left + 1)
                {
                    count = right - left + 1;
                }

                sum -= nums[left++];
            }

        }

        return count == INT_MAX ? 0 : count;
    }
};

2. 无重复字符的最长字符串

class Solution 
{
public:
    int lengthOfLongestSubstring(string s) 
    {
        //简单代替哈希表
        int hash[128] = {0};
        int left = 0;
        int right = 0;
        int s_len = 0;
        int len = 0;
        int size = s.length();
        while(right < size)
        {
            hash[s[right]]++;
            len++;
            while(hash[s[right]] >= 2)
            {
                hash[s[left]]--;
                left++;
                len--;
            }

            if(s_len < len)
            {
                s_len = len;
            }

            right++;
        }

        return s_len;
    }
};

3. 最大连续1的个数

class Solution 
{
public:
    int longestOnes(vector<int>& nums, int k) 
    {
        int zero = 0;
        int ret = 0;
        //逻辑执行顺序
        //判断,++,计算
        //哪里是窗口
        for(int right = 0, left = 0; right < nums.size(); right++)
        {
           if (nums[right] == 0)
			{
				zero++;
			}

			while (zero > k)
			{
				if (nums[left] == 0)
				{
					zero--;
				}
				left++;
			}
			
            ret = max(right - left + 1, ret);
        }

        return ret;
    }
};

4. 将x减到0的最小操作数

图示:
在这里插入图片描述

class Solution 
{
public:
    int minOperations(vector<int>& nums, int x) 
    {
        //正难则反
        //暴力枚举法的优化
        int sum = 0;
        for(auto e : nums)
        {
            sum += e;
        }
        //负数
        int target = sum - x;
        int reverse_sum = 0;
        int count = 0;

        if(target < 0)
        {
            return -1;
        }

        if(target == 0)
        {
            return nums.size();
        }

        for(int left = 0, right = 0; right < nums.size(); right++)
        {
            reverse_sum += nums[right];

            while(reverse_sum > target)
            {
                reverse_sum -= nums[left];
                left++;
            }

            //区间,左闭右闭
            //找最大
            if(reverse_sum == target && right - left + 1 > count)
            {
                cout << right << ' ' << left << endl;
                count = right - left + 1;
            }
        }

        return count == 0 ? -1 : nums.size() - count;
    }
};

5. 水果成篮

class Solution 
{
public:
    int totalFruit(vector<int>& fruits) 
    {
        //遍历双指针
        //哈希表,种类
        int size = fruits.size();
        int* hash = (int*)malloc(size * sizeof(int));
        memset(hash, 0, size * sizeof(int));
        int kind = 0;
        int len = 0;
        for(int right = 0, left = 0; right < fruits.size(); right++)
        {
            //进窗口
            if(hash[fruits[right]] == 0)
            {
                kind++;
            }
            hash[fruits[right]]++;

            //出窗口
            while(kind > 2)
            {
                hash[fruits[left]]--;
                if(hash[fruits[left]] == 0)
                {
                    kind--;
                }

                left++;
            }

            //判断
            if(right - left + 1 > len)
            {
                len = right - left + 1;
            }
        }

        return len;
    }
};

6. 找到字符串中所有字母异位词

尝试:

class Solution 
{
public:
    vector<int> findAnagrams(string s, string p) 
    {
        vector<int> count;
        //暴力求解,列出所有长度为字符串p的字串
        //进行匹配,哈希表大小26,下标
        //记录,判断
        int hash[26] = {0};
        //所指定下标处都为1
        //遍历的指针
        for(int right = 0, left = 0; right < s.length(); right++)
        {
            //进窗口
            hash[s[right] - 'a']++;

            //出窗口
            while(right - left + 1 > p.length())
            {
                hash[s[left] - 'a']--;
                left++;
            }

            //判断
            if(right - left + 1 == p.length())
            {
                int flag = 1;
                for(int i = 0; i < p.length(); i++)
                {
                    //相同的字符
                    hash[p[i] - 'a']--;
                }

                for(int i = 0; i < p.length(); i++)
                {
                    if(hash[p[i] - 'a'] != 0)
                    {
                        flag = 0;
                        break;
                    }
                }

                for(int i = 0; i < p.length(); i++)
                {
                    hash[p[i] - 'a']++;
                }

                if(flag)
                {
                    count.push_back(left);
                }
            }
        }

        return count;
    }
};

优化1:(判断方式改为两个哈希表)

class Solution 
{
public:
    vector<int> findAnagrams(string s, string p) 
    {
        vector<int> count;
        int hash1[26] = {0};
        int hash2[26] = {0};
        for(int i = 0; i < p.length(); i++)
        {
            hash2[p[i] - 'a']++;
        }
        
        for(int right = 0, left = 0; right < s.length(); right++)
        {
            //进窗口
            hash1[s[right] - 'a']++;

            //出窗口
            while(right - left + 1 > p.length())
            {
                hash1[s[left] - 'a']--;
                left++;
            }

            //判断
            //两个哈希表
            if(right - left + 1 == p.length())
            {
                int flag = 1;
                for(int i = 0; i < 26; i++)
                {
                    if(hash1[i] !=hash2[i])
                    {
                        flag = 0;
                        break;
                    }
                }

                if(flag)
                {
                    count.push_back(left);
                }
            }
        }

        return count;
    }
};

优化2:(计数:判断优化)

class Solution 
{
public:
    vector<int> findAnagrams(string s, string p) 
    {
        vector<int> ret;
        int hash1[26] = {0};
        int hash2[26] = {0};
        int count1 = 0;
        int count2 = 0;
        //标记并计算有多少个有效字符
        for(int i = 0; i < p.length(); i++)
        {
            hash2[p[i] - 'a']++;
            count2++;
        }
        
        for(int right = 0, left = 0; right < s.length(); right++)
        {
            //有效字符,且没有多余
            if(hash2[s[right] - 'a'] && hash1[s[right] - 'a'] < hash2[s[right] - 'a'])
            {
                count1++;
            }
            //进窗口
            hash1[s[right] - 'a']++;

            //出窗口
            while(right - left + 1 > p.length())
            {
                //是有效字符,且出窗口的有效字符不是多余
                if(hash2[s[left] - 'a'] && hash1[s[left] - 'a'] <= hash2[s[left] - 'a'])
                {
                    count1--;
                }
                hash1[s[left] - 'a']--;
                left++;
            }

            //判断
            //两个哈希表
            if(right - left + 1 == p.length() && count1 == count2)
            {
                ret.push_back(left);
            }
        }

        return ret;
    }
};

7. 串联所有单词的子串

class Solution
{
public:
	vector<int> findSubstring(string s, vector<string>& words)
	{
		vector<int> ret;

		//right + words[0].length()边界问题
		for (int i = 0; i < words[0].length(); i++)
		{
            map<string, int> m1;
            map<string, int> m2;
            for (auto e : words)
            {
                m1[e]++;
                //cout << m1[e] << endl;
                m2[e] = 0;
            }

            int count1 = 0;
		    int count2 = words.size();
			//后续再遍历,少遍历一步
			for (int right = i, left = i; right + words[0].length() - 1 < s.length(); right += words[0].length())
			{
				//进窗口
				string part1(s.begin() + right, s.begin() + right + words[0].length());
				//cout << part << endl;
				//有效字符
				if (m1[part1] > 0 && m2[part1] < m1[part1])
				{
					count1++;
				}
				m2[part1]++;
				//cout << m2[part1] << endl;

				//出窗口
				int size = words.size() * words[0].length();
				//cout << size << endl;
				while (right + words[0].length() - left > size)
				{
					string part2(s.begin() + left, s.begin() + left + words[0].length());
					//没有发生重复的有效字符
					//只要是有效字符就--
					if (m1[part2] > 0 && m2[part2] <= m1[part2])
					{
						count1--;
					}
					m2[part2]--;
					left += words[0].length();
				}

				//判断
				if (right + words[0].length() - left == words.size() * words[0].length() && count1 == count2)
				{
					count.push_back(left);
				}
			}
		}

		return ret;
	}
};

8. 最小覆盖子串

在这里插入图片描述

class Solution {
public:
    string minWindow(string s, string t) 
    {
        //可以用数组代替map时,数组更优
        int hash1[128] = {0};
        int hash2[128] = {0};
        //记录有效字符种类
        int kind1 = 0;
        for(auto e : t)
        {
            if(hash1[e]++ == 0)
            {
                kind1++;
            }
            //hash1[e]++;
        }

        //用有效字符种类的判断方式优于记录有效字符个数的判断方式
        int kind2 = 0;
        //记录子串长度
        int len = INT_MAX;
        //记录子串起始位置
        int begin = -1;
        for(int right = 0, left = 0; right < s.length(); right++)
        {
            //先进窗口再判断是否为有效字符
            //hash2[s[right]]++;
            if(hash1[s[right]] == ++hash2[s[right]])
            {
                kind2++;
            }

            //当遍历字符中包含有效字符时,进行判断,记录与出窗口操作
            while(kind1 == kind2)
            {
                //判断
                if(right - left + 1 < len)
                {
                    begin = left;
                    len = right - left + 1;
                }

                //出窗口
                //先判断再出窗口
                if(hash1[s[left]] && hash1[s[left]] == hash2[s[left]])
                {
                    kind2--;
                }
                hash2[s[left]]--;
                left++;
            }
        }

        //判断有无子串
        if(begin == -1)
        {
            return "";
        }
        else
        {
            //取子串
            return s.substr(begin, len);
        }
    }
};
举报

相关推荐

0 条评论