-
第一題和第三題一樣。就是求約數
-
第二題就是模擬
-
第4題使用線段樹
-
1,3題程式碼
-
實際上發現沒有下面程式碼複雜,比如: a*b = n ,列舉a就好,a在[1, sqrt(n)內。
import java.util.*;
class Solution {
public int numberOfPairs(int[] nums1, int[] nums2, int k) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums2.length; i++) {
map.put(nums2[i], map.getOrDefault(nums2[i], 0) + 1);
}
int ans = 0;
for (int i = 0; i < nums1.length; i++) {
if (nums1[i] % k == 0) {
List<Integer> list = getfactor(nums1[i] / k);
for (int num : list) {
ans += map.getOrDefault(num, 0);
}
}
}
return ans;
}
public List<int[]> getPrime(int n) {
List<int[]> ans = new LinkedList<>();
int p = 2;
while (p * p <= n) {
if (n % p == 0) {
int cnt = 0;
while (n % p == 0) {
n = n / p;
cnt++;
}
ans.add(new int[]{p, cnt});
}
p++;
}
if (n != 1) {
ans.add(new int[]{n,1});
}
return ans;
}
public List<Integer> getfactor(int n) {
List<int[]> ans = getPrime(n);
List<Integer> res = new ArrayList<>();
res.add(1);
dfs(ans, res, 0, 1);
return res;
}
public int pow(int base, int p) {
if (p == 0) {
return 1;
}
if (p == 1) {
return base;
}
int ans = pow(base, p / 2);
if (p % 2 == 0) {
return ans * ans;
}
return ans * ans * base;
}
public void dfs(List<int[]> ans, List<Integer> res, int depth, int curr) {
if (depth == ans.size()) {
if (curr != 1) {
res.add(curr);
}
return;
}
int[] tmp = ans.get(depth);
int p = tmp[0];
int cnt = tmp[1];
for (int c = 0; c <= cnt; c++) {
dfs(ans, res, depth + 1, curr * pow(p, c));
}
}
}
- 第2題
class Solution {
public String compressedString(String word) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.length(); ) {
char c = word.charAt(i);
int j = i;
int cnt = 0;
while(j < word.length() && cnt < 9 && word.charAt(j) == c) {
cnt++;
j++;
}
sb.append(String.format("%d%c",cnt,c));
i = j;
}
return sb.toString();
}
}
- 第4題 線段樹
class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
int ans = solution.maximumSumSubsequence(new int[]{
3,5,9
}, new int[][]{
{1, -2},
{0, -3}
});
System.out.println(ans);
}
public int maximumSumSubsequence(int[] nums, int[][] queries) {
int n = nums.length;
Segment segment = new Segment(0, n - 1);
for (int i = 0; i < nums.length; i++) {
segment.update(i, nums[i]);
}
long ans = 0;
for (int i = 0; i < queries.length; i++) {
int pos = queries[i][0];
int x = queries[i][1];
nums[pos] = x;
segment.update(pos, x);
ans += segment.max();
ans %= 1000_000_007;
}
return (int)ans;
}
class Segment {
int l, r;
Segment left, right;
// f00, f01, f10, f11
// f00 表示左端點一定不選,右端點也一定不選 最大值
// f01 表示左端點一定不選,右端點可選可不選 最大值
// f10 表示左端點可選可不選,右端點一定不選 最大值
// f11 表示左端點可選可不選,右端點可選可不選 最大值
int[] f = new int[4];
public Segment(int l, int r) {
this.l = l;
this.r = r;
}
public int max() {
return Math.max(Math.max(f[0], f[1]), Math.max(f[2], f[3]));
}
public void update(int L, int value) {
if (l == L && L == r) {
f[0] = 0;
f[1] = 0;
f[2] = 0;
f[3] = Math.max(value, 0);
return;
}
int mid = (l + r) / 2;
if (this.left == null) {
this.left = new Segment(l, mid);
}
if (this.right == null) {
this.right = new Segment(mid + 1, r);
}
if (L <= mid) {
this.left.update(L, value);
} else {
this.right.update(L, value);
}
pushup();
}
public void pushup() {
int[] a = this.left.f;
int[] b = this.right.f;
f[0] = Math.max(a[0] + b[2], a[1] + b[0]);
f[1] = Math.max(a[0] + b[3], a[1] + b[1]);
f[2] = Math.max(a[2] + b[2], a[3] + b[0]);
f[3] = Math.max(a[2] + b[3], a[3] + b[1]);
}
}
}