LeetCode Weekly Contest 26

LeetCode Weekly Contest 26
[2017-04-02]

  1. Longest Uncommon Subsequence I
  2. Longest Uncommon Subsequence II
  3. Friend Circles
  4. Split Array with Equal Sum

Longest Uncommon Subsequence I

Given a group of two strings, you need to find the longest uncommon subsequence of this group of two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be two strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn’t exist, return -1.

Example 1:

1
2
3
4
5
Input: "aba", "cdc"
Output: 3
Explanation: The longest uncommon subsequence is "aba" (or "cdc"),
because "aba" is a subsequence of "aba",
but not a subsequence of any other strings in the group of two strings.

Note:

  • Both strings’ lengths will not exceed 100.
  • Only letters from a ~ z will appear in input strings.

code

两个字符串相同就无解;
否则输出两个字符串的长度中较大者;

1
2
3
4
5
6
7
8
class Solution {
public:
int findLUSlength(string a, string b) {
if (a == b)
return -1;
return max(int(a.size()), int(b.size()));
}
};


Longest Uncommon Subsequence II

Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be a list of strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn’t exist, return -1.

Example 1:

1
2
Input: "aba", "cdc", "eae"
Output: 3

Note:

  • All the given strings’ lengths will not exceed 10.
  • The length of the given list will be in the range of [2, 50].

code

因为最大长度为10;
所以把每个长度有哪些字符串记录下来;
然后从字符串长度由大到小枚举len;
假设这个答案序列为len长度的某个字符串;
然后看看len长度的字符串有没有和它一样的字符串(即出现两次及以上)
有的话不行,找另外一个长度为len的字符串;
否则
再看看这个字符串是不是长度比len长的字符串的子串;
如果不是的话;
就表示找到了;
直接输出len;
否则继续找长度为len的另外的字符串;
判断一个字符串是不是另外一个字符串的子串其实很简单的;
O(l1+l2)就能判断出来;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Solution {
public:
bool judge(string s, vector<string>& strs){
int cnt = 0;
for(int i = 0; i < strs.size(); i++){
int idx = 0;
for(int j = 0; j < strs[i].size(); j++){
if(idx == s.size()){
break;
}
if(s[idx] == strs[i][j]){
idx++;
}
}
if(idx == s.size()){
cnt++;
}
}
if(cnt == 1){
return true;
}
return false;
}
int findLUSlength(vector<string>& strs) {
map<string, int> m;
int maxLength = -1;
for(int s = 0; s < strs.size(); s++){
string a = strs[s];
/*Method 1
When we add a letter Y to our candidate longest uncommon subsequence answer of X,
it only makes it strictly harder to find a common subsequence. Thus our candidate
longest uncommon subsequences will be chosen from the group of words itself.
m[a]++;
*/
/*Method 2*/
for(int i = a.size(); i >= 1; i--){
for(int j = 0; j <= a.size() - i; j++){
if(m.find(a.substr(j, i)) == m.end()){
m.insert(map<string,int>::value_type(a.substr(j, i), 1));
}else{
m[a.substr(j, i)] ++;
}
}
}
}
for(auto ite = m.begin(); ite!= m.end(); ite++){
string sd = ite->first;
int i = ite->second;
if(i == 1){
if(judge(sd, strs))
maxLength = max(maxLength, (int)sd.size());
}
}
return maxLength;
}
};


Friend Circles

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:

1
2
3
4
5
6
7
Input:
[[1,1,0],
[1,1,0],
[0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle.
The 2nd student himself is in a friend circle. So return 2.

Example 2:

1
2
3
4
5
6
7
Input:
[[1,1,0],
[1,1,1],
[0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends,
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

Note:

  • N is in range [1,200].
  • M[i][i] = 1 for all students.
  • If M[i][j] = 1, then M[j][i] = 1.

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Solution {
public:
int* unionFind;
void unionFunction(int i, int j, int unionFind[], int size){
if(i == j){
return ;
}
int tmpI = i;
while(tmpI != unionFind[tmpI]){
tmpI = unionFind[tmpI];
}
int tmpJ = j;
while(tmpJ != unionFind[tmpJ]){
tmpJ = unionFind[tmpJ];
}
if(tmpJ > tmpI){
unionFind[tmpJ] = tmpI;
}
if(tmpJ < tmpI){
unionFind[tmpI] = tmpJ;
}
}
int findCircleNum(vector<vector<int>>& M) {
int* unionFind = new int[M.size()];
for(int i = 0; i < M.size(); i++){
unionFind[i] = i;
}
for(int i = 0; i < M.size(); i++){
for(int j = 0; j < M.size(); j++){
if(M[i][j])
unionFunction(i, j, unionFind,M.size());
}
}
set<int> s;
for(int i = 0; i < M.size(); i++){
if(i == unionFind[i])
s.insert(i);
}
return s.size();
}
};

Split Array with Equal Sum

Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions:

  1. 0 < i, i + 1 < j, j + 1 < k < n - 1
  2. Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be equal.

where we define that subarray (L, R) represents a slice of the original array starting from the element indexed L to the element indexed R.

Example:

1
2
3
4
5
6
7
8
Input: [1,2,1,2,1,2,1]
Output: True
Explanation:
i = 1, j = 3, k = 5.
sum(0, i - 1) = sum(0, 0) = 1
sum(i + 1, j - 1) = sum(2, 2) = 1
sum(j + 1, k - 1) = sum(4, 4) = 1
sum(k + 1, n - 1) = sum(6, 6) = 1

Note:

  • 1 <= n <= 2000.
  • Elements in the given array will be in range [-1,000,000, 1,000,000].

code

先枚举要删除的3个元素中的中间那个元素j;
然后把整个序列分成左边和右边两个部分;
然后再左边的序列中枚举i;
然后把0..j-1分成0..i-1和i+1..j-1两个部分;
然后看这两个部分各自的和是不是相同;
相同的话把和用map记录一下;
然后再枚举
右半部分即第3个元素k;
分成
j+1..k-1和k+1..n-1两个部分;
看看各自的和是不是相同;
相同的话,看看刚才左半部分记录的map里面有没有这个和;
有的话输出true
复杂度接近O(n^2)吧->用了map哦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
public:
map <int, int> dic;
int pre[N],n;
bool splitArray(vector<int>& nums) {
n = nums.size();
pre[0] = nums[0];
for(int i = 1; i < n; i++)
{
pre[i] = pre[i - 1] + nums[i];
}
for(int j = 1; j < n - 1; j++)
{
dic.clear();
int l = 0, r = j - 1;
for(int i = l + 1; i < r; i++)
{
if (pre[i] - nums[i] == pre[r] - pre[i])
{
dic[pre[r] - pre[i]] = 1;
}
}
l = j + 1, r = n - 1;
for(int i = l + 1; i < r; i++)
{
if (dic[pre[r] - pre[i]] && (pre[i] - nums[i] - pre[j]) == (pre[r] - pre[i]))
return true;
}
}
return false;
}
};