1、子集
思路:之前的最长上升子序列针对的是一个数,本题说的是一个整体Node(x和y)都有有序,求他们的最长上升子序列。固定一个求另一个。将x由小到大排序,x相同时y由大到小排序(故意放错以免将x相同情况也计算入内),y的最长上升子序列就是答案了。
因为dp方法求lis会超时,所以这题只能用二分查找了。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
for (int k = 0; k < m; k++) {
int n = sc.nextInt();
int[][] matrix = new int[n][2];
for (int i = 0; i < n; i++) {
matrix[i][0] = sc.nextInt();
}
for (int i = 0; i < n; i++) {
matrix[i][1] = sc.nextInt();
}
//sort
Arrays.sort(matrix, (x, y) -> (x[0] != y[0] ? x[0] - y[0] : y[1] - x[1]));
int res = fun(matrix);
System.out.println(res);
}
}
//二分查找求y的最长上升子序列
public static int fun(int[][] matrix) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < matrix.length; i++) {
int poker = matrix[i][1];
int left = 0, right = list.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (list.get(mid) < poker) {
left = mid + 1;
} else {
right = mid - 1;
}
}
if (left == list.size()) {
list.add(poker);
} else {
list.set(left, poker);
}
}
return list.size();
}
}
9、合法连续子段
滑动窗口,不满足条件右移,满足条件左移,左移时更新答案。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int k = sc.nextInt();
int[] nums = new int[m];
for (int i = 0; i < m; i++) {
nums[i] = sc.nextInt();
}
HashMap<Integer, Integer> window = new HashMap<>();
int left = 0, right = 0, start = 0, end = 0, valid = 0, res = 0;
while (right < nums.length) {
int x = nums[right];
right++;
int time = window.getOrDefault(x, 0);
window.put(x, time + 1);
if (time + 1 > valid) valid = time + 1;
while (valid == k) {
res += nums.length - right + 1;
int y = nums[left];
left++;
int time2 = window.get(y);
if (time2 == k) {
valid--;
}
window.put(y, time2 - 1);
}
}
System.out.println(res);
}
}
10、两个序列
思路:设置映射规则,求最长连续上升子序列长度,返回n-lis。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int m=sc.nextInt();
int[] a=new int[m];
int[] b=new int[m];
HashMap<Integer, Integer> map=new HashMap<>();
for(int j=0; j<m; j++){
a[j]=sc.nextInt();
map.put(a[j],j);
}
for(int j=0; j<m; j++){
b[j]=sc.nextInt();
b[j]=map.get(b[j]);
}
int len=fun(b);
System.out.println(m-len);
}
public static int fun(int[] b){
int res=1;
int cnt=1;
for(int i=1; i<b.length; i++){
if(b[i-1]<b[i]) cnt++;
else cnt=1;
res=Math.max(res, cnt);
}
return res;
}
}
16进制数中1的个数
package com.atguigu;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
char[] chars = str.substring(2).toCharArray();
int res = 0;
int[] map = new int[]{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
for (int i = 0; i < chars.length; i++) {
if (Character.isLetter(chars[i])) res += map[chars[i] - 'a' + 10];
else res += map[chars[i] - '0'];
}
System.out.println(res);
}
}