Skip to content

Improved tasks 999, 1825, 3425 #1941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,97 +1,61 @@
package g0901_1000.s0999_available_captures_for_rook;

// #Easy #Array #Matrix #Simulation #2022_03_31_Time_0_ms_(100.00%)_Space_41.8_MB_(28.74%)
// #Easy #Array #Matrix #Simulation #2025_03_13_Time_0_ms_(100.00%)_Space_40.75_MB_(94.97%)

@SuppressWarnings("java:S135")
public class Solution {
private int[] directions = new int[] {0, 1, 0, -1, 0};

public int numRookCaptures(char[][] board) {
int m = board.length;
int n = board[0].length;
int rowR = -1;
int colR = -1;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// Find the position of the rook
int rookRow = -1;
int rookCol = -1;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (board[i][j] == 'R') {
rowR = i;
colR = j;
rookRow = i;
rookCol = j;
break;
}
}
}
int[] count = {0};
for (int i = 0; i < 4; i++) {
int neighborRow = rowR + directions[i];
int neighborCol = colR + directions[i + 1];
if (neighborRow >= 0
&& neighborRow < m
&& neighborCol >= 0
&& neighborCol < n
&& board[neighborRow][neighborCol] != 'B') {
if (directions[i] == 0 && directions[i + 1] == 1) {
extracted(board, n, count, neighborRow, neighborCol);
} else if (directions[i] == 1 && directions[i + 1] == 0) {
extracted1(board, m, count, neighborRow, neighborCol);
} else if (directions[i] == 0 && directions[i + 1] == -1) {
extracted(board, count, neighborRow, neighborCol);
} else {
extracted1(board, count, neighborRow, neighborCol);
}
}
}
return count[0];
}

private void extracted(char[][] board, int[] count, int neighborRow, int neighborCol) {
while (neighborCol >= 0) {
if (board[neighborRow][neighborCol] == 'p') {
count[0]++;
break;
} else if (board[neighborRow][neighborCol] == 'B') {
break;
} else {
neighborCol--;
}
}
}

private void extracted(char[][] board, int n, int[] count, int neighborRow, int neighborCol) {
while (neighborCol < n) {
if (board[neighborRow][neighborCol] == 'p') {
count[0]++;
break;
} else if (board[neighborRow][neighborCol] == 'B') {
break;
} else {
neighborCol++;
}
}
}

private void extracted1(char[][] board, int[] count, int neighborRow, int neighborCol) {
while (neighborRow >= 0) {
if (board[neighborRow][neighborCol] == 'p') {
count[0]++;
if (rookRow != -1) {
break;
} else if (board[neighborRow][neighborCol] == 'B') {
break;
} else {
neighborRow--;
}
}
}

private void extracted1(char[][] board, int m, int[] count, int neighborRow, int neighborCol) {
while (neighborRow < m) {
if (board[neighborRow][neighborCol] == 'p') {
count[0]++;
break;
} else if (board[neighborRow][neighborCol] == 'B') {
break;
} else {
neighborRow++;
// Define the four directions: up, right, down, left
int[][] directions = {
// up
{-1, 0},
// right
{0, 1},
// down
{1, 0},
// left
{0, -1}
};
int captureCount = 0;
// Check each direction
for (int[] dir : directions) {
int row = rookRow;
int col = rookCol;
while (true) {
// Move one step in the current direction
row += dir[0];
col += dir[1];
// Check if out of bounds
if (row < 0 || row >= 8 || col < 0 || col >= 8) {
break;
}
// If we hit a bishop, we're blocked
if (board[row][col] == 'B') {
break;
}
// If we hit a pawn, we can capture it and then we're blocked
if (board[row][col] == 'p') {
captureCount++;
break;
}
// Otherwise (empty square), continue in the same direction
}
}
return captureCount;
}
}
171 changes: 50 additions & 121 deletions src/main/java/g1801_1900/s1825_finding_mk_average/MKAverage.java
Original file line number Diff line number Diff line change
@@ -1,141 +1,70 @@
package g1801_1900.s1825_finding_mk_average;

// #Hard #Design #Heap_Priority_Queue #Ordered_Set #Queue
// #2022_05_06_Time_83_ms_(60.59%)_Space_96.3_MB_(77.83%)
// #2025_03_13_Time_37_ms_(100.00%)_Space_100.84_MB_(46.09%)

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.TreeMap;
import java.util.LinkedList;
import java.util.TreeSet;

@SuppressWarnings("java:S2184")
public class MKAverage {
private final double m;
private final double k;
private final double c;
private double avg;
private final Bst middle;
private final Bst min;
private final Bst max;
private final Deque<Integer> q;
private final int capacity;
private final int boundary;
private final int[] nums;
private final TreeSet<Integer> numSet;
private final LinkedList<Integer> order;

public MKAverage(int m, int k) {
this.m = m;
this.k = k;
this.c = m - k * 2;
this.avg = 0;
this.middle = new Bst();
this.min = new Bst();
this.max = new Bst();
this.q = new ArrayDeque<>();
this.capacity = m;
this.boundary = k;
nums = new int[100001];
numSet = new TreeSet<>();
order = new LinkedList<>();
}

public void addElement(int num) {
if (min.size < k) {
min.add(num);
q.offer(num);
return;
}
if (max.size < k) {
min.add(num);
max.add(min.removeMax());
q.offer(num);
return;
}

if (num >= min.lastKey() && num <= max.firstKey()) {
middle.add(num);
avg += num / c;
} else if (num < min.lastKey()) {
min.add(num);
int val = min.removeMax();
middle.add(val);
avg += val / c;
} else if (num > max.firstKey()) {
max.add(num);
int val = max.removeMin();
middle.add(val);
avg += val / c;
}

q.offer(num);

if (q.size() > m) {
num = q.poll();
if (middle.containsKey(num)) {
avg -= num / c;
middle.remove(num);
} else if (min.containsKey(num)) {
min.remove(num);
int val = middle.removeMin();
avg -= val / c;
min.add(val);
} else if (max.containsKey(num)) {
max.remove(num);
int val = middle.removeMax();
avg -= val / c;
max.add(val);
if (order.size() == capacity) {
int numToDelete = order.removeFirst();
nums[numToDelete] = nums[numToDelete] - 1;
if (nums[numToDelete] == 0) {
numSet.remove(numToDelete);
}
}
nums[num]++;
numSet.add(num);
order.add(num);
}

public int calculateMKAverage() {
if (q.size() < m) {
return -1;
}
return (int) avg;
}

static class Bst {
TreeMap<Integer, Integer> map;
int size;

public Bst() {
this.map = new TreeMap<>();
this.size = 0;
}

void add(int num) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
size++;
}

void remove(int num) {
int count = map.getOrDefault(num, 1) - 1;
if (count > 0) {
map.put(num, count);
} else {
map.remove(num);
if (order.size() == capacity) {
int skipCount = boundary;
int numsCount = capacity - 2 * boundary;
int freq = capacity - 2 * boundary;
int sum = 0;
for (int num : numSet) {
int count = nums[num];
if (skipCount < 0) {
sum += num * Math.min(count, numsCount);
numsCount -= Math.min(count, numsCount);
} else {
skipCount -= count;
if (skipCount < 0) {
sum += num * Math.min(Math.abs(skipCount), numsCount);
numsCount -= Math.min(Math.abs(skipCount), numsCount);
}
}
if (numsCount == 0) {
break;
}
}
size--;
}

int removeMin() {
int key = map.firstKey();

remove(key);

return key;
}

int removeMax() {
int key = map.lastKey();

remove(key);

return key;
}

boolean containsKey(int key) {
return map.containsKey(key);
}

int firstKey() {
return map.firstKey();
}

int lastKey() {
return map.lastKey();
return sum / freq;
}
return -1;
}
}

/*
* Your MKAverage object will be instantiated and called as such:
* MKAverage obj = new MKAverage(m, k);
* obj.addElement(num);
* int param_2 = obj.calculateMKAverage();
*/
Loading