LeetCode 6 - Z 字形变换

题目链接:LeetCode 6 - Z 字形变换

我们可以把 numRows + numRows - 2 个字符分为一组,记这个组的大小为 groupSize。然后通过分类讨论计算出当前这个元素变换后的行号和列号,然后做双关键字排序即可。

渐进时间复杂度 \(O(n \log n)\),其中 \(n\)s 的长度。

注意特别判断numRows = 1的情况。

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
struct Coordinate {
char c;
int x;
int y;

bool operator < (const Coordinate &rhs) const {
return (x == rhs.x) ? (y < rhs.y) : (x < rhs.x);
}
};

class Solution {
private:
vector <Coordinate> v;

int getRId(int x, int groupSize, int numRows) {
x %= groupSize;
if (x < numRows) {
return x;
} else {
return (numRows - 1) - (x - numRows + 1);
}
}

int getCId(int x, int groupSize, int numRows) {
int ans = x / groupSize * (numRows - 1);
x %= groupSize;
if (x < numRows) {
return ans;
} else {
return ans + x - numRows + 1;
}
}

public:
string convert(string s, int numRows) {
if (numRows == 1) return s;
int groupSize = numRows * 2 - 2;
for (int i = 0; i < s.size(); ++i) {
int rId = getRId(i, groupSize, numRows);
int cId = getCId(i, groupSize, numRows);
v.push_back({s[i], rId, cId});
}
sort(v.begin(), v.end());
string ret = "";
for (auto e: v) {
ret.push_back(e.c);
}
return ret;
}
};