CD79 一种消息接收并打印的结构设计
public class CD79_1
{
public static class Node
{
public int num;
public Node next;
public Node(int num)
{
this.num = num;
}
}
public static class MessageBox
{
private HashMap<Integer, Node> headMap;
private HashMap<Integer, Node> tailMap;
private int lastPrint;
public MessageBox()
{
headMap = new HashMap<Integer, Node>();
tailMap = new HashMap<Integer, Node>();
lastPrint = 0;
}
public void receive(int num)
{
if (num < 1) return;
Node cur = new Node(num);
headMap.put(num, cur);
tailMap.put(num, cur);
if (tailMap.containsKey(num - 1))
{
tailMap.get(num - 1).next = cur;
tailMap.remove(num - 1);
headMap.remove(num);
}
if (headMap.containsKey(num + 1))
{
cur.next = headMap.get(num + 1);
tailMap.remove(num);
headMap.remove(num + 1);
}
if (headMap.containsKey(lastPrint + 1))
print(num);
}
private void print(int num)
{
Node node = headMap.get(++lastPrint);
headMap.remove(lastPrint);
while (node != null)
{
System.out.println(node.num + " " + num);
node = node.next;
lastPrint++;
}
tailMap.remove(--lastPrint);
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
MessageBox messageBox = new MessageBox();
int n = in.nextInt();
for (int i = 0; i < n; i++)
messageBox.receive(in.nextInt());
}
}
CD80 随时找到数据流的中位数
public class CD80_1
{
public static PriorityQueue<Integer> minHeap = new PriorityQueue<>();
public static PriorityQueue<Integer> maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1);
public static int count = 0;
public static void Insert(Integer num)
{
count++;
if (count % 2 != 0)
{
minHeap.add(num);
maxHeap.add(minHeap.poll());
}
else
{
maxHeap.add(num);
minHeap.add(maxHeap.poll());
}
}
public static Double GetMedian()
{
if (minHeap.size() == maxHeap.size())
return (minHeap.peek() + maxHeap.peek()) / 2.0;
else
return maxHeap.peek() * 1.0;
}
}
CD81 在两个长度相等的排序数组中找到上中位数他❗
/*❗*/
public class CD81_1
{
public static int solution(int[] nums1, int[] nums2)
{
return getKthElement(nums1, nums2, nums1.length);
}
public static int getKthElement(int[] nums1, int[] nums2, int k)
{
int length1 = nums1.length, length2 = nums2.length;
int index1 = 0, index2 = 0;
while (true)
{
// 边界情况
if (index1 == length1)
return nums2[index2 + k - 1];
if (index2 == length2)
return nums1[index1 + k - 1];
if (k == 1)
return Math.min(nums1[index1], nums2[index2]);
// 正常情况
int half = k / 2;
int newIndex1 = Math.min(index1 + half, length1) - 1;
int newIndex2 = Math.min(index2 + half, length2) - 1;
int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
if (pivot1 <= pivot2)
{
k -= (newIndex1 - index1 + 1);
index1 = newIndex1 + 1;
}
else
{
k -= (newIndex2 - index2 + 1);
index2 = newIndex2 + 1;
}
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr1 = new int[n];
int[] arr2 = new int[n];
for (int i = 0; i < n; i++)
arr1[i] = in.nextInt();
for (int i = 0; i < n; i++)
arr2[i] = in.nextInt();
System.out.println(solution(arr1, arr2));
}
}
CD82 在两个排序数组中找到第 k 小的数❗
/*❗*/
public class CD82_1
{
public static int solution(int[] nums1, int[] nums2, int k)
{
int length1 = nums1.length, length2 = nums2.length;
int index1 = 0, index2 = 0;
while (true)
{
// 边界情况
if (index1 == length1)
return nums2[index2 + k - 1];
if (index2 == length2)
return nums1[index1 + k - 1];
if (k == 1)
return Math.min(nums1[index1], nums2[index2]);
// 正常情况
int half = k / 2;
int newIndex1 = Math.min(index1 + half, length1) - 1;
int newIndex2 = Math.min(index2 + half, length2) - 1;
int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
if (pivot1 <= pivot2)
{
k -= (newIndex1 - index1 + 1);
index1 = newIndex1 + 1;
}
else
{
k -= (newIndex2 - index2 + 1);
index2 = newIndex2 + 1;
}
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt(), m = in.nextInt(), k = in.nextInt();
int[] arr1 = new int[n];
int[] arr2 = new int[m];
for (int i = 0; i < n; i++)
arr1[i] = in.nextInt();
for (int i = 0; i < m; i++)
arr2[i] = in.nextInt();
System.out.println(solution(arr1, arr2, k));
}
}
CD83 两个有序数组间相加和的 Top k 问题
public class CD83_1
{
public static class Node implements Comparable<Node>
{
public int index1;
public int index2;
public int val;
public Node(int index1, int index2, int val)
{
this.index1 = index1;
this.index2 = index2;
this.val = val;
}
@Override
public int compareTo(Node o)
{
return o.val - this.val;
}
}
public static int[] solution(int[] arr1, int[] arr2, int k)
{
PriorityQueue<Node> que = new PriorityQueue<>();
HashSet<String> set = new HashSet<>();
int res[] = new int[k];
int len1 = arr1.length - 1, len2 = arr2.length - 1, index = -1;
que.add(new Node(len1, len2, arr1[len1] + arr2[len2]));
while (++index < k)
{
Node pollNode = que.poll();
int curIdx1 = pollNode.index1, curIdx2 = pollNode.index2;
res[index] = pollNode.val;
if (!set.contains(curIdx1 + "_" + (curIdx2 - 1)))
{
set.add(curIdx1 + "_" + (curIdx2 - 1));
que.add(new Node(curIdx1, curIdx2 - 1, arr1[curIdx1] + arr2[curIdx2 - 1]));
}
if (!set.contains((curIdx1 - 1) + "_" + curIdx2))
{
set.add((curIdx1 - 1) + "_" + curIdx2);
que.add(new Node(curIdx1 - 1, curIdx2, arr1[curIdx1 - 1] + arr2[curIdx2]));
}
}
return res;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt(), k = in.nextInt();
int[] arr1 = new int[n];
int[] arr2 = new int[n];
for (int i = 0; i < n; i++)
arr1[i] = in.nextInt();
for (int i = 0; i < n; i++)
arr2[i] = in.nextInt();
int[] res = solution(arr1, arr2, k);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD84 出现次数的 Top k 问题
public class CD84_1
{
public static class Node implements Comparable<Node>
{
public String str;
public int times;
public Node(String s, int t)
{
str = s;
times = t;
}
@Override
public int compareTo(Node o)
{
if (this.times != o.times)
return o.times - this.times;
else
return this.str.compareTo(o.str);
}
}
public static void solution(String[] arr, int topK)
{
HashMap<String, Integer> map = new HashMap<>();
PriorityQueue<Node> que = new PriorityQueue<>();
for (String word : arr)
{
if (!map.containsKey(word))
map.put(word, 1);
else
map.put(word, map.get(word) + 1);
}
for (String word : map.keySet())
que.add(new Node(word, map.get(word)));
while (topK-- > 0)
{
Node pollNode = que.poll();
System.out.println(pollNode.str + " " + pollNode.times);
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt(), k = in.nextInt();
in.nextLine();
String[] arr = new String[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextLine();
solution(arr, k);
}
}
CD85 Manacher 算法
public class CD85_1
{
public static int solution(String s)
{
int sc = -1, sr = -1, ansCenter = 0, ansLen = 0;
int[] p = new int[2 * s.length() + 1];
StringBuilder str = new StringBuilder();
str.append('#');
for (char ch : s.toCharArray())
str.append(ch + "#");
for (int i = 0; i < str.length(); i++)
{
p[i] = sr > i ? Math.min(p[2 * sc - i], sr - i) : 1;
while (i + p[i] < str.length() && i - p[i] > -1 && str.charAt(i + p[i]) == str.charAt(i - p[i]))
++p[i];
if (sr < i + p[i])
{
sr = i + p[i];
sc = i;
}
if (ansLen < p[i])
{
ansLen = p[i];
ansCenter = i;
}
}
int start = (ansCenter - ansLen + 1) / 2;
System.out.println(s.substring(start, start + ansLen - 1));
return ansLen - 1;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
System.out.println(solution(s));
}
}
CD86 Manacher 算法(进阶)
public class CD86_1
{
public static String solution(String s)
{
int sc = -1, sr = -1;
int[] p = new int[2 * s.length() + 1];
StringBuilder str = new StringBuilder();
str.append('#');
for (char ch : s.toCharArray())
str.append(ch + "#");
for (int i = 0; i < str.length(); i++)
{
p[i] = sr > i ? Math.min(p[2 * sc - i], sr - i) : 1;
while (i + p[i] < str.length() && i - p[i] > -1 && str.charAt(i + p[i]) == str.charAt(i - p[i]))
++p[i];
if (sr < i + p[i])
{
sr = i + p[i];
sc = i;
}
}
int start = (sc - p[sc] + 1) / 2;
return new StringBuilder(s.substring(0, start)).reverse().toString();
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
System.out.println(solution(s));
}
}
CD87 KMP 算法
public class CD87_1
{
public static void solution(String s1, String s2)
{
ArrayList<Integer> ans = new ArrayList<>();
int[] next = getNext(s2);
int i = 0, j = 0;
while (i < s1.length())
{
if (s1.charAt(i) == s2.charAt(j))
{
i++;
j++;
}
else if (next[j] == -1) i++;
else j = next[j];
if (j == s2.length())
{
ans.add(i - j);
j = 0;
}
}
if (!ans.isEmpty())
System.out.println(ans.stream().map(String::valueOf).collect(Collectors.joining(" ")));
else
System.out.println(-1);
}
public static int[] getNext(String s)
{
if (s.length() == 1) return new int[]{-1};
int[] next = new int[s.length()];
int pos = 2, cn = 0;
next[0] = -1;
next[1] = 0;
while (pos < s.length())
{
if (s.charAt(pos - 1) == s.charAt(cn))
next[pos++] = ++cn;
else if (cn > 0)
cn = next[cn];
else
next[pos++] = 0;
}
return next;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s1, s2;
s1 = in.nextLine();
s2 = in.nextLine();
solution(s1, s2);
}
}
CD88 丢棋子问题✍
CD89 画匠问题✍
CD90 邮局选址问题✍