[LeetCode ] Weekly Contest 111

 Valid Mountain Array

Given an array A of integers, return true 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 with 0 < 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 of N 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), let N = S.length.

Return any permutation A of [0, 1, ..., N] such that for all i = 0, ..., N-1:

  • If S[i] == "I", then A[i] < A[i+1]
  • If S[i] == "D", then A[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 in A

题意:构造一个最短串,是给出的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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值