Leetcode进阶之路——Biweekly Contest 3

  1. Two Sum Less Than K
    1099
    给定一个整型数组和K,选取数组中的两个数使其和最接近K
    先对原数组排序,头尾指针遍历,找到第一个小于K的数即可,实时更新最接近K的值
#define fo(i, a, b) for(int i = a; i < b; ++i)

class Solution {
public:
    int twoSumLessThanK(vector<int>& A, int K) {
        sort(A.begin(), A.end());
        int len = A.size();
        int maxsum = -1;
        fo(i, 0, len)
        {
            int cursum = -1;
            for(int j = len - 1; j > i; --j)
            {
                if(A[j] + A[i] < K)
                {
                    cursum = A[j] + A[i];
                    break;
                }
            }
            maxsum = max(maxsum, cursum);
        }
        return maxsum;
    }
};
  1. Find K-Length Substrings With No Repeated Characters
    1100
    给定一个字符串和一个K,判断原字符串 长为K的子串中各字符均互不相同的子串个数
    用一个哈希表存储各字符出现的个数,若哈希表大小刚好为K,则该子串符号要求,否则往后移下标,直至遍历完
#define fo(i, a, b) for(int i = a; i < b; ++i)

class Solution {
public:
    int numKLenSubstrNoRepeats(string S, int K) {
        if(S.length() < K) return 0;
        map<char, int> m;
        int cnt = 0;
       fo(i, 0, K)
        {
            if(m[S[i]] == 0)
                cnt++;
            m[S[i]]++;
        }
        int res = 0;
        if(cnt == K) res++;
        fo(i, K, S.length())
        {
            if(m[S[i - K]]-- == 1) cnt--;
            if(m[S[i]]++ == 0) cnt++;
            if(cnt == K) res++;
        }
        return res;
    }
};
  1. The Earliest Moment When Everyone Become Friends
    1101
    给定一个二维数组,每个元素为[timestamp, ida, idb], 表示在timestamp这一时刻,ida和idb两个人互相成为了朋友
    同时给定一个N,判断所有的N个人互相成为朋友的最早时刻
    典型的并查集,对原log按timestamp先排序,只要满足find(ida) != find(idb)的次数 = N - 1,就表示该时刻所有人都互相成为朋友,否则返回-1
int father[101];

class Solution {
public:
	int find(int x)
	{
		int t = x;
		while (father[t] != t)
			t = father[t];
		return t;
	}

	void mix(int a, int b)
	{
		int fa = find(a), fb = find(b);
		if (fa != fb)
			father[fa] = fb;
	}

	int earliestAcq(vector<vector<int>>& logs, int N) {
  		 //按时间排序
		sort(logs.begin(), logs.end(),
			[&](const vector<int>& a, const vector<int>& b)
		{
			return a[0] < b[0];
		});
		int res = INT_MAX;
		vector<int> people(N, 0);
		for (int i = 0; i < N; ++i)
			father[i] = i;
		for (auto v : logs)
		{
			if (find(v[1]) != find(v[2]))
			{
				N--;
				mix(v[1], v[2]);
			}
			if (N == 1) res = min(res, v[0]);
		}
		if (res == INT_MAX) return -1;
		else return res;
	}
};
  1. Path With Maximum Minimum Value
    1102
    给定一个二维数组,判断所有从左上到右下的路径中,路径分数最大的分数值
    某条路径的分数为该路径中值最小的数
    典型的bfs,由于A[i][j] <= 1e9,因此可以想到用二分法,初始low = 0, high = 1e9,mid = (low + high) / 2
    依次二分,若存在路径,其分数>=mid,则令low = mid + 1,否则令high = mid - 1
#define fo(i, a, b) for(int i = a; i < b; ++i)

int dx[4] = { 1, -1, 0, 0 };
int dy[4] = { 0, 0, 1, -1 };
class Solution {
public:
	bool miniPathbfs(vector<vector<int>> A, int row, int col, int lim)
	{
        if(A[0][0] < lim) return false;
		vector<vector<int>> visited(row, vector<int>(col, 0));
		queue<pair<int, int>> q;
		q.emplace(make_pair(0, 0));
		visited[0][0] = 1;
		while (!q.empty())
		{
			int cnt = q.size();
			fo(i, 0, cnt)
			{
				pair<int, int> p = q.front();
				q.pop();
				fo(j, 0, 4)
				{
					int x = p.first + dx[j], y = p.second + dy[j];
					if (x >= 0 && x < row && y >= 0 && y < col && visited[x][y] == 0 && A[x][y] >= lim)
					{
						if (x == row - 1 && y == col - 1 && A[x][y] >= lim) return true;
						visited[x][y] = 1;
						q.emplace(make_pair(x, y));
					}
				}
			}
		}
		return false;
	}
	
	int maximumMinimumPath(vector<vector<int>>& A) {
		int row = A.size(), col = A[0].size();
		int low = 0, high = 1e9;
		while (low <= high)
		{
			int mid = (low + high) / 2;
			if (miniPathbfs(A, row, col, mid))
				low = mid + 1;
			else high = mid - 1;
		}
		return low - 1;
	}

};
发布了109 篇原创文章 · 获赞 108 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/u013700358/article/details/94314770
今日推荐