You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class36;
// 来自网易
// 规定L[1]对应aL[2]对应bL[3]对应c...L[25]对应y
// S1 = a
// S(i) = S(i-1) + L[i] + reverse(invert(S(i-1)));
// 解释invert操作
// S1 = a
// S2 = aby
// 假设invert(S(2)) = 甲乙丙
// a + 甲 = 26, 那么 甲 = 26 - 1 = 25 -> y
// b + 乙 = 26, 那么 乙 = 26 - 2 = 24 -> x
// y + 丙 = 26, 那么 丙 = 26 - 25 = 1 -> a
// 如上就是每一位的计算方式所以invert(S2) = yxa
// 所以S3 = S2 + L[3] + reverse(invert(S2)) = aby + c + axy = abycaxy
// invert(abycaxy) = yxawyba, 再reverse = abywaxy
// 所以S4 = abycaxy + d + abywaxy = abycaxydabywaxy
// 直到S25结束
// 给定两个参数n和k返回Sn的第k位是什么字符n从1开始k从1开始
// 比如n=4k=2表示S4的第2个字符是什么返回b字符
public class Code01_ReverseInvertString {
public static int[] lens = null;
public static void fillLens() {
lens = new int[26];
lens[1] = 1;
for (int i = 2; i <= 25; i++) {
lens[i] = (lens[i - 1] << 1) + 1;
}
}
// 求sn中的第k个字符
// O(n), s <= 25 O(1)
public static char kth(int n, int k) {
if (lens == null) {
fillLens();
}
if (n == 1) { // 无视k
return 'a';
}
// sn half
int half = lens[n - 1];
if (k <= half) {
return kth(n - 1, k);
} else if (k == half + 1) {
return (char) ('a' + n - 1);
} else {
// sn
// 我需要右半区从左往右的第a个
// 需要找到s(n-1)从右往左的第a个
// 当拿到字符之后invert一下就可以返回了
return invert(kth(n - 1, ((half + 1) << 1) - k));
}
}
public static char invert(char c) {
return (char) (('a' << 1) + 24 - c);
}
// 为了测试
public static String generateString(int n) {
String s = "a";
for (int i = 2; i <= n; i++) {
s = s + (char) ('a' + i - 1) + reverseInvert(s);
}
return s;
}
// 为了测试
public static String reverseInvert(String s) {
char[] invert = invert(s).toCharArray();
for (int l = 0, r = invert.length - 1; l < r; l++, r--) {
char tmp = invert[l];
invert[l] = invert[r];
invert[r] = tmp;
}
return String.valueOf(invert);
}
// 为了测试
public static String invert(String s) {
char[] str = s.toCharArray();
for (int i = 0; i < str.length; i++) {
str[i] = invert(str[i]);
}
return String.valueOf(str);
}
// 为了测试
public static void main(String[] args) {
int n = 20;
String str = generateString(n);
int len = str.length();
System.out.println("测试开始");
for (int i = 1; i <= len; i++) {
if (str.charAt(i - 1) != kth(n, i)) {
System.out.println(i);
System.out.println(str.charAt(i - 1));
System.out.println(kth(n, i));
System.out.println("出错了!");
break;
}
}
System.out.println("测试结束");
}
}