问题:删列造序 ||
给定由 N
个小写字母字符串组成的数组 A
,其中每个字符串长度相等。
选取一个删除索引序列,对于 A
中的每个字符串,删除对应每个索引处的字符。
比如,有 A = ["abcdef", "uvwxyz"]
,删除索引序列 {0, 2, 3}
,删除后 A
为["bef", "vyz"]
。
假设,我们选择了一组删除索引 D
,那么在执行删除操作之后,最终得到的数组的元素是按 字典序(A[0] <= A[1] <= A[2] ... <= A[A.length - 1]
)排列的,然后请你返回 D.length
的最小可能值。
示例 1:
输入:["ca","bb","ac"] 输出:1 解释: 删除第一列后,A = ["a", "b", "c"]。 现在 A 中元素是按字典排列的 (即,A[0] <= A[1] <= A[2])。 我们至少需要进行 1 次删除,因为最初 A 不是按字典序排列的,所以答案是 1。
示例 2:
输入:["xc","yb","za"] 输出:0 解释: A 的列已经是按字典序排列了,所以我们不需要删除任何东西。 注意 A 的行不需要按字典序排列。 也就是说,A[0][0] <= A[0][1] <= ... 不一定成立。
示例 3:
输入:["zyx","wvu","tsr"] 输出:3 解释: 我们必须删掉每一列。
提示:
1 <= A.length <= 100
1 <= A[i].length <= 100
链接:https://leetcode-cn.com/contest/weekly-contest-114/problems/delete-columns-to-make-sorted-ii/
分析:
目标是删除最小的行数是的剩余是按照字典排序
1.字典排序:从头到尾逐个字符对比,如果相同比下一个,直到有区别或者结束。
azz < baa
abc < abd
2.如果是多个字符串对比,如果某个已经比出大小,那么没必要看后面的
str1:a?????
str2:a?????
str3:c?????
str1<=str2<str3,后面只需要比较str1 str2
3.如果字符串组中是严格有序的,即没有相等的,就可以直接得出结果
str1:a?????
str2:b?????
str3:c?????
str1<str2<str3,没必要比较后面的。
4,如果不是有序的在需要将该列去除
最终做法即为依次每个string取一个字符,看是否有序以及是否需要继续比下去,
如果无序,删除该列
如果有序,也不需要继续比,返回结果
如果有序,但是需要继续比,那就继续比。
AC Code:
1 class Solution { 2 public: 3 //dp 4 int minDeletionSize(vector<string>& A) { 5 int ret = 0; 6 vector<string> strs; 7 if (A.size() <= 1) 8 { 9 return 0; 10 } 11 if (A[0].size() < 1) 12 { 13 return 0; 14 } 15 for (unsigned int i = 0; i < A.size(); i++) 16 { 17 string tmp = ""; 18 tmp += A[i][0]; 19 strs.emplace_back(tmp); 20 } 21 int neednextcheck = 0; 22 bool isordered; 23 isordered = IsOrdered(strs, neednextcheck); 24 if (isordered == true && neednextcheck == 0) 25 { 26 return ret; 27 } 28 if (isordered == false) 29 { 30 ret++; 31 32 for (unsigned int i = 0; i < A.size(); i++) 33 { 34 string tmp = ""; 35 strs[i]=tmp; 36 } 37 } 38 for (unsigned int i = 1; i < A[0].size(); i++) 39 { 40 vector<string> tmpstrs(strs); 41 for (unsigned int j = 0; j < A.size(); j++) 42 { 43 tmpstrs[j] += A[j][i]; 44 } 45 isordered = IsOrdered(tmpstrs, neednextcheck); 46 if (isordered == true && neednextcheck == 0) 47 { 48 return ret; 49 } 50 if (isordered == false) 51 { 52 ret++; 53 } 54 else 55 { 56 strs = tmpstrs; 57 } 58 } 59 return ret; 60 } 61 bool IsOrdered(vector<string> strs,int& neednextcheck) 62 { 63 bool ret = true; 64 vector<string> OrderedStrs(strs); 65 //string tmp = strs[0]; 66 neednextcheck = 0; 67 for (unsigned int i = 1; i < strs.size(); i++) 68 { 69 if (strs[i] == strs[i - 1]) 70 { 71 neednextcheck = 1; 72 break; 73 } 74 } 75 sort(OrderedStrs.begin(), OrderedStrs.end()); 76 for (unsigned int i = 0; i < strs.size(); i++) 77 { 78 if (OrderedStrs[i] != strs[i]) 79 { 80 return false; 81 } 82 } 83 84 return ret; 85 } 86 };
其他:
1,忽略了好多提示,一方面提示有思路上的提示,另一方面可以避免无用功,比如这个,有明确提到A.length A[0].length 都是大于等于1的,取[0]位置的值完全可以直接取的
3,第一code:
1 #pragma GCC optimize("O3", "unroll-loops") 2 // God Help me !! 3 #include <bits/stdc++.h> 4 using namespace std; 5 // #define watch(x) cout << (#x) << " is " << (x) << endl 6 7 #define FILES freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout) 8 #define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0) 9 #define FIXED cout << fixed << setprecision(20) 10 #define RANDOM srand(time(nullptr)) 11 #define int long long 12 // #define MOD 1000000007 13 #define sz(a) (ll)a.size() 14 #define pll pair<ll,ll> 15 #define rep(i,a,b) for(int i=(int)a;i<(int)b;i++) 16 #define sep(i,a,b) for(int i=(int)a;i>=(int)b;i--) 17 #define mll map<int,int> 18 #define vl vector<int> 19 #define pb push_back 20 #define lb lower_bound 21 #define ub upper_bound 22 #define all(a) a.begin(),a.end() 23 #define F first 24 #define S second 25 #define endl "\n" 26 #define MAXN6 3000005 27 #define MAXN3 3005 28 #define MAXN5 300005 29 30 #define watch(...) ZZ(#__VA_ARGS__, __VA_ARGS__) 31 template <typename Arg1> void ZZ(const char* name, Arg1&& arg1){std::cerr << name << " = " << arg1 << endl;} 32 template <typename Arg1, typename... Args>void ZZ(const char* names, Arg1&& arg1, Args&&... args) 33 { 34 const char* comma = strchr(names + 1, ','); 35 std::cerr.write(names, comma - names) << " = " << arg1; 36 ZZ(comma, args...); 37 } 38 39 40 class Solution { 41 public: 42 int minDeletionSize(vector<string>& A) { 43 int n = A.size(), m = A[0].size(); 44 int ans = 0; 45 vector<string> B; 46 for (int i = 0; i < n; i++) { 47 B.push_back(""); 48 } 49 for (int i = 0; i < m; i++) { 50 bool isOk = true; 51 for (int j = 1; j < n; j++) { 52 if (B[j] == B[j-1] && A[j][i] < A[j-1][i]) { 53 isOk = false; 54 ans++; 55 break; 56 } 57 } 58 if (isOk) { 59 for (int j = 0; j < n; j++) 60 B[j] += A[j][i]; 61 } 62 } 63 return ans; 64 } 65 };