# 第七十一周ARTS总结

# Algorithm

7ms | 35.02% Run time
39.6MB | 17.72% Memory

public List<String> restoreIpAddresses(String s) {
    // 思路是在s中确定三个位置放点
    // 先找到中间的那个点
    // 然后分别找第一个和第三个点
    List<String> ans = new ArrayList<>();

    List<Integer> middles = findMiddlePoint(s);

    for (Integer middle : middles) {
        findAndLoadRestPoint(s, middle, ans);
    }

    return ans;
}

/**
 * 找出中间的那个点
 *
 * @param s
 * @return
 */
private List<Integer> findMiddlePoint(String s) {
    List<Integer> ans = new ArrayList<>();
    char[] chars = s.toCharArray();

    // 左边的长度在2~6之间,右边的长度在2~6之间,然后注意0开头的情况
    for (int i = 0; i < chars.length; i++) {
        // 左边的长度不能小于2
        if (i + 1 < 2) {
            continue;
        }

        // 左边如果是0开头,长度不能超过4
        if (chars[0] == '0' && i + 1 > 4) {
            break;
        }

        // 左边的长度不能超过6
        if (i + 1 > 6) {
            break;
        }

        // 右边长度不能小于2
        if (chars.length - i - 1 < 2) {
            break;
        }

        // 右边如果是0开头,长度不能超过4
        if (chars[i + 1] == '0' && chars.length - i - 1 > 4) {
            continue;
        }

        // 右边的长度不能超过6
        if (chars.length - i - 1 > 6) {
            continue;
        }

        ans.add(i);
    }

    return ans;
}

/**
 * 找到剩余的点,并把生成的字符串放进ans内
 *
 * @param s
 * @param middlePoint
 * @param ans
 */
private void findAndLoadRestPoint(String s, int middlePoint, List<String> ans) {
    List<int[]> leftPart = new ArrayList<>();
    List<int[]> rightPart = new ArrayList<>();

    // 找到左右的点
    findPart(s, 0, middlePoint + 1, leftPart);
    findPart(s, middlePoint + 1, s.length(), rightPart);

    for (int[] left : leftPart) {
        for (int[] right : rightPart) {
            ans.add(left[0] + "." + left[1] + "." + right[0] + "." + right[1]);
        }
    }
}

/**
 * 找到从[startIndex, end)之间满足条件的一个点
 *
 * @param s
 * @param startIndex
 * @param end
 * @param part
 */
private void findPart(String s, int startIndex, int end, List<int[]> part) {
    char[] chars = s.toCharArray();

    for (int i = startIndex; i < end - 1; i++) {
        int p1, p2;

        if (chars[startIndex] == '0') {
            if (chars[startIndex + 1] == '0' && end - startIndex > 2) {
                break;
            }

            p1 = 0;
            p2 = Integer.parseInt(s.substring(startIndex + 1, end));

            if (p2 <= 255) {
                int[] temp = new int[]{p1, p2};
                part.add(temp);
            }

            break;
        } else {
            if (chars[i + 1] == '0' && end > i + 2) {
                continue;
            }

            p1 = Integer.parseInt(s.substring(startIndex, i + 1));
            p2 = Integer.parseInt(s.substring(i + 1, end));

            if (p1 <= 255 && p2 <= 255) {
                int[] temp = new int[]{p1, p2};
                part.add(temp);
            }
        }
    }
}
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

# Review

# Tip

  • ndk的选择
    • 国内:armeabi-v7a
    • 国外:armeabi-v7a, arm64-v8a
    • DEBUG:x86, armeabi-v7a, arm64-v8ax86主要用于Windows上的模拟器)
  • 线程池的生命周期
    • RUNNING
    • SHUTDOWN
    • STOP
    • TIDYING
    • TERMINATED
  • ThreadPoolExecutor中的参数
    • corePoolSize:线程池的核心线程数
    • workQueue:任务队列
    • maximumPoolSize:线程池支持的最大线程数
    • keepAliveTime:非核心线程空闲时的存活时间
    • unit:存活时间的单位
    • threadFactory:创建线程的工厂
    • handler:拒绝策略
  • APP启动优化
    • 启动分类
      1. 冷启动
      2. 热启动:APP从后台到前台
      3. 温启动:APP进程仍然存在,重新启动活动
    • 获取启动时间
      1. adb shell am start -W [packageName]/[packageName.xxActivity]
      2. 使用代码打点:attachBaseContext时开启,界面完全展示后结束
      3. 利用工具
        • TraceView
        • Systrace
    • 常用优化策略
      1. 异步加载
        • 利用CountDownLatch来处理某些需要初始化完成后才能运行的情况
        • 利用启动器的思维
      2. 延迟加载:利用IdleHandler在主线程空闲的时候进行分批初始化
      3. 提前加载:利用androidx-startup
      4. 其他优化:给Activity添加一个自定义的主题,使用一个默认的界面
  • 触摸事件的传递顺序:Activity -> PhoneWindow -> DecorView -> ViewGroup -> View

# Share

暂无内容

更新时间: 10/20/2022, 7:04:01 AM