[LeetCode ] Weekly Contest 111
Valid Mountain Array
Given an array
A
of integers, returntrue
if and only if it is a valid mountain array.Recall that A is a mountain array if and only if:
A.length >= 3
- There exists some
i
with0 < i < A.length - 1
such that:
A[0] < A[1] < ... A[i-1] < A[i]
A[i] > A[i+1] > ... > A[B.length - 1]
題意:判斷一個數組是否是山脈陣列
思路:預處理出每一位向左的連續遞減長度和向右的連續遞減長度,然後列舉一遍判斷每一個元素向左的加向右的加一是否等於陣列長度就行了。
C程式碼:
bool validMountainArray(int* A, int ASize) { if(ASize < 3) return false; int pre[10005]; int post[10005]; int i; pre[0] = 0; for(i = 1; i < ASize; i++) { if(A[i] > A[i - 1]) { pre[i] = pre[i - 1] + 1; } else { pre[i] = 0; } } post[ASize - 1] = 0; for(i = ASize - 2; i >= 0; i--) { if(A[i] > A[i + 1]) { post[i] = post[i + 1] + 1; } else { post[i] = 0; } } bool flag = false; for(i = 1; i <= ASize - 2; i++) { if(pre[i] + post[i] + 1 == ASize) { flag = true; } } return flag; }
Delete Columns to Make Sorted
We are given an array
A
ofN
lowercase letter strings, all of the same length.Now, we may choose any set of deletion indices, and for each string, we delete all the characters in those indices.
For example, if we have a string
"
abcdef
"
and deletion indices{0, 2, 3}
, then the final string after deletion is"
bef
"
.Suppose we chose a set of deletion indices
D
such that after deletions, each remaining column in A is in non-decreasing sorted order.Formally, the
c
-th column is[A[0][c], A[1][c], ..., A[A.length-1][c]]
Return the minimum possible value of
D.length
.
題意:給出一個字串陣列,字串陣列的每一個字串長度都相同,問最少刪除多少列,使剩下的列都是非減序的。
思路:雙重for迴圈判斷即可
java程式碼:
public class Solution {
public int minDeletionSize(String[] A) {
int ans = 0;
for(int i = 0; i < A[0].length(); i++) {
boolean f1 = false;
for(int j = 0; j < A.length; j++) {
if(j == 0) continue;
if(A[j].charAt(i) < A[j - 1].charAt(i)) {
f1 = true;
}
}
if(f1 == true) {
ans++;
}
}
return ans;
}
}
DI String Match
Given a string
S
that only contains "I" (increase) or "D" (decrease), letN = S.length
.Return any permutation
A
of[0, 1, ..., N]
such that for alli = 0, ..., N-1
:
- If
S[i] == "I"
, thenA[i] < A[i+1]
- If
S[i] == "D"
, thenA[i] > A[i+1]
題意:給出一個只有I和D字元的字串,I表示A[i]<A[i+1],D表示A[i]>A[i+1],找出與之相匹配的排列
思路:所有的I對應從0開始的升序,所有的D對應從n開始的降序,最後一位根據倒數第二位來判斷。
Java程式碼:
public class Solution {
public int[] diStringMatch(String S) {
int n = S.length() + 1;
int[] ans = new int[n];
int a = 0,b = S.length();
for(int i = 0; i < S.length(); i++) {
if(S.charAt(i) == 'I') {
ans[i] = a++;
}
else {
ans[i] = b--;
}
}
if(S.charAt(S.length() - 1) == 'D') {
ans[n - 1] = ans[n - 2] - 1;
}
else {
ans[n - 1] = ans[n - 2] + 1;
}
return ans;
}
}
Find the Shortest Superstring
Given an array A of strings, find any smallest string that contains each string in
A
as a substring.We may assume that no string in
A
is substring of another string inA
題意:構造一個最短串,是給出的n個字串都是所構造的字串的字串。
思路:轉化為旅行商問題,先建圖,比如第i個字串caaa,第j個字串aaac,則cost[i][j]為1,然後就轉化為n個點必須經過一次僅一次,求最小花費,旅行商問題。這裡我設定了一個虛點0,cost[0][i]為strlen(A[i]),這樣就把第一個字串的長度也計算了。
C程式碼:
int calOverlap(char* a,char* b)
{
int overlap = 0;
int len1 = strlen(a);
int len2 = strlen(b);
int i,j,k;
for(i = 0; i < len2; i++) {
for(k = 0,j = len1 - 1 - i; j < len1; j++,k++) {
if(a[j] != b[k]) break;
}
if(j == len1) overlap = i + 1;
}
return len2 - overlap;
}
char* shortestSuperstring(char** A, int ASize)
{
int i,j,k;
int cost[13][13],dp[13][1 << 13],path[13][1 << 13];
for(i = 0; i < ASize; i++) {
for(j = 0; j < ASize; j++) {
cost[i + 1][j + 1] = calOverlap(A[i],A[j]);
}
}
memset(dp,0x3f3f3f3f,sizeof(dp));
memset(path,-1,sizeof(path));
dp[0][0] = 0;
for(i = 1; i <= ASize; i++) {
cost[0][i] = strlen(A[i - 1]);
cost[i][0] = 0;
dp[i][0] = cost[i][0];
}
for(j = 0; j <= ((1 << (ASize + 1)) - 1); j++) {
for(i = 0; i <= ASize; i++) {
if( (j & (1 << i)) == 0) {
for(k = 0; k <= ASize; k++) {
if((j & (1 << k)) != 0) {
if(dp[i][j] > cost[i][k] + dp[k][j ^ (1 << k)]) {
dp[i][j] = cost[i][k] + dp[k][j ^ (1 << k)];
path[i][j] = k;
}
}
}
}
}
}
char* res = (char*) malloc(sizeof(char) * 10005);
int t = ((1 << (ASize + 1)) - 2);
int pre = 0,cnt = 0,cur,len,st;
while(path[pre][t] != -1) {
cur = path[pre][t];
len = strlen(A[cur - 1]);
for(i = len - cost[pre][cur]; i < len; i++) {
res[cnt++] = A[cur - 1][i];
}
pre = cur;
t ^= (1 << cur);
}
res[cnt++] = '\0';
return res;
}