Skip to main content

42 posts tagged with "leetcode"

View All Tags

· One min read
Junhe Chen

binary search left bound and right bound

class Solution {
public boolean isMajorityElement(int[] nums, int target) {
// search left
int left = 0, right = nums.length - 1;
while(left <= right){
int pivot = left + (right - left) / 2;
if(nums[pivot] >= target){
// we shrink to left
right = pivot - 1;
}else{
// it is too small
left = pivot + 1;
}
}
int p1 = left;
left = 0; right = nums.length - 1;
// find right boundry
while(left <= right){
int pivot = left + (right - left) / 2;
if(nums[pivot] > target){
// we shrink to left
right = pivot - 1;
}else{
// it is too small
left = pivot + 1;
}
}
int p2 = right;
return p2 - p1 + 1 > nums.length /2;
}
}

· One min read
Junhe Chen

bit manipulation

class Solution {
public int minFlips(int a, int b, int c) {
int res = 0;
while(a != 0 || b != 0 || c!= 0){
// there is more we going to exampe
if((c & 1) == 1){
// we have c curr bit at one
if ((a & 1) == 0 && (b & 1) == 0) {
// we need to flip this c
res++;
}
}else{
res += (a & 1) + (b & 1); // flip a or b to 0 if needed
}
//exam next bit

a >>= 1;
b >>= 1;
c >>= 1;

}
return res;
}
}

· One min read
Junhe Chen

// for this question we know it is tree structure so we dont need visited array, simply go down the tree would be good.

class Solution {
public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
// build the graph
List<List<Integer>> graph = new ArrayList<>();
for(int i = 0; i < n; i ++){
graph.add(new ArrayList<>());
}

for(int i = 0; i < n; i ++){
if (manager[i] != -1) {
graph.get(manager[i]).add(i);
}
}

// do the bfs
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{headID,informTime[headID]});
int res = 0;
while(!q.isEmpty()){
int[] curr = q.poll();
res = Math.max(res,curr[1]);
for(int next : graph.get(curr[0])){
q.add(new int[]{next,curr[1] + informTime[next]});
}
}
return res;
}
}

· 2 min read
Junhe Chen

the algorithm of this question is not hard, simple bfs or dfs is sufficent, but the appoarch to link bombs together based on their radius takes a edge to come up with.

class Solution {
public int maximumDetonation(int[][] bombs) {
// we can treat as a graph
Map<Integer,List<Integer>> graph = new HashMap<>();
int n = bombs.length;

// building the graph
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++){
// we need to make sure we have different bomb
if(i != j){
int xi = bombs[i][0], yi = bombs[i][1], ri = bombs[i][2];
int xj = bombs[j][0], yj = bombs[j][1];

// if xi can trigger xj we create that edge
if((long) ri * ri >= (long)(xi - xj) * (xi - xj) + (long)(yi - yj) * (yi - yj)){
graph.putIfAbsent(i,new ArrayList<>());
graph.get(i).add(j);
}
}
}
}

// now we can do dfs or bfs
int res = 0;
for(int i = 0; i < n; i ++){
int count = bfs(i, new HashSet<>(),graph);
res = Math.max(res,count);
}
return res;
}
private int bfs(int start, Set<Integer> visited, Map<Integer,List<Integer>> graph){
Queue<Integer> q = new LinkedList<>();
visited.add(start);
q.add(start);
int res = 0;
while(!q.isEmpty()){
res ++;
int curr = q.poll();
if(graph.containsKey(curr)){
for(int next : graph.get(curr)){
if(!visited.contains(next)){
// this is a new valid bomb
q.add(next);
visited.add(next);
}
}
}


}
return res;
}
}

· One min read
Junhe Chen
class UndergroundSystem {
HashMap<Integer,Pair<String,Integer>> checkIn;
HashMap<String,Pair<Double,Integer>> log;
public UndergroundSystem() {
checkIn = new HashMap<>();
log = new HashMap<>();
}

public void checkIn(int id, String stationName, int t) {
// check in the customer
checkIn.putIfAbsent(id,new Pair<>(stationName,t));
}

public void checkOut(int id, String stationName, int t) {
Pair<String,Integer> info = checkIn.get(id);
String startStation = info.getKey();
int startTime = info.getValue();
String route = startStation + "->" + stationName;
double tripTime = t - startTime;

if(log.containsKey(route)){
double loggedTime = log.get(route).getKey();
int loggedTrip = log.get(route).getValue();
log.put(route,new Pair<>(tripTime + loggedTime, loggedTrip + 1));
}else{
log.put(route,new Pair<>(tripTime,1));
}
// remove the entry
checkIn.remove(id);
}

public double getAverageTime(String startStation, String endStation) {
// Lookup how many times this journey has been made, and the total time.
String routeKey = startStation + "->" + endStation;
Double totalTime = log.get(routeKey).getKey();
int totalTrips = log.get(routeKey).getValue();
// The average is simply the total divided by the number of trips.
return totalTime / totalTrips;
}
}

/**
* Your UndergroundSystem object will be instantiated and called as such:
* UndergroundSystem obj = new UndergroundSystem();
* obj.checkIn(id,stationName,t);
* obj.checkOut(id,stationName,t);
* double param_3 = obj.getAverageTime(startStation,endStation);
*/

· 2 min read
Junhe Chen

Easy question , you can use three int variable or array is faster and easier.

class ParkingSystem {
int[] lot;
public ParkingSystem(int big, int medium, int small) {
lot = new int[]{big,medium,small};
}

public boolean addCar(int carType) {
if(lot[carType - 1] == 0) return false;
lot[carType - 1] --;
return true;
}
}

348

class TicTacToe {
int[] rows,cols;
int diagonal,antiDiagonal;

public TicTacToe(int n) {
rows = new int[n];
cols = new int[n];
diagonal = 0;
antiDiagonal = 0;
}

public int move(int row, int col, int player) {
int n = rows.length;
// determine the mark by player
int mark = (player == 1) ? 1 : -1;
// mark the row and col
rows[row] += mark;
cols[col] += mark;
// mark the diagonal or antiDiagonal if applies
if(row == col) diagonal += mark;
if(col == (n - row - 1)) antiDiagonal += mark;
// if any row or col scores n that means our new mark connected a row col diagonal or antiDiagonal;
if(Math.abs(rows[row]) == n|| Math.abs(cols[col]) == n || Math.abs(diagonal) == n || Math.abs(antiDiagonal) == n) return player;
// no winer
return 0;
}
}

/**
* Your TicTacToe object will be instantiated and called as such:
* TicTacToe obj = new TicTacToe(n);
* int param_1 = obj.move(row,col,player);
*/

· One min read
Junhe Chen
class Solution {
Integer[][] memo;
int newCuts[];
public int minCost(int n, int[] cuts) {
int m = cuts.length;
memo = new Integer[m + 2][m + 2];
newCuts = new int[m + 2];
System.arraycopy(cuts, 0, newCuts, 1, m);
newCuts[m + 1] = n;
Arrays.sort(newCuts);
return dp(0,newCuts.length - 1);
}
private int dp(int left, int right){
// base case
if(right - left == 1) return 0;

if(memo[left][right] != null) return memo[left][right];

int res = Integer.MAX_VALUE;
for(int pivot = left + 1; pivot < right; pivot ++){
int cost = dp(left,pivot) + dp(pivot,right) + newCuts[right] - newCuts[left];
res = Math.min(res,cost);
}
memo[left][right] = res;
return res;
}
}

· One min read
Junhe Chen

basica dp question calc score based on what you can get - what opponent can get.

class Solution {
Integer[] dp;
public String stoneGameIII(int[] stoneValue) {
int n = stoneValue.length;
dp = new Integer[n + 1];
int res = helper(stoneValue,0);
if(res > 0){
return "Alice";
}
if(res < 0){
return "Bob";
}
return "Tie";
}
private int helper(int[] stones, int curr){
// base case
if(curr == stones.length) return 0; // no more stone
if(dp[curr] != null) return dp[curr]; // solved case

// our socre is what we have - what opponent can have
int res = stones[curr] - helper(stones,curr + 1);
if(curr + 2 <= stones.length){
// we can take up to 2 stones
res = Math.max(res,stones[curr] + stones[curr + 1] - helper(stones,curr + 2));
}
if(curr + 3 <= stones.length){
res = Math.max(res,stones[curr] + stones[curr + 1] + stones[curr + 2] - helper(stones,curr + 3));
}
return dp[curr] = res;
}
}

· One min read
Junhe Chen
class Solution {
Integer[][][] memo;
public int stoneGameII(int[] piles) {
memo = new Integer[2][piles.length + 1][piles.length + 1];
return stoneGame(piles,0,1,0);
}
private int stoneGame(int[] piles, int curr, int M, int alex){
// base case
if(curr >= piles.length) return 0; // no more stone
if(memo[alex][curr][M] != null) return memo[alex][curr][M];
int res = alex == 1 ? 1000000 : -1;
int stones = 0;
for(int x = 1; x <= Math.min(2 * M, piles.length - curr); x ++){
stones += piles[curr + x - 1];
if(alex == 0){
res = Math.max(res,stones + stoneGame(piles,curr + x,Math.max(M,x),1));
}else{
res = Math.min(res,stoneGame(piles,curr + x, Math.max(M,x),0));
}
}
return memo[alex][curr][M] = res;
}
}

· 2 min read
Junhe Chen

The apporach is simple, we want sum to be as big as possible, but more importantly our nums2(min) has to be bigger because it grows faster.

So we sort by nums2 at each index, we want to have our nums2 to be at max

we add all k item into the priority queue, and once we got the score, we want to make sure our score is actually good, so we want to keep going on nums2, while we polls the smallest from the nums1 and keep update items.

class Solution {
public long maxScore(int[] nums1, int[] nums2, int k) {
// we want nums2 be as big as possible
int n = nums1.length;
int[][] pairs = new int[n][2];
for(int i = 0; i < n; i ++){
pairs[i] = new int[]{nums1[i],nums2[i]};
}
Arrays.sort(pairs,(a,b) -> b[1] - a[1]); // we want to sort the pair by biggest in nums2
PriorityQueue<Integer> pq = new PriorityQueue<>(k,(a,b) -> a - b);

long topK = 0;
for(int i = 0; i < k; i ++){
topK += pairs[i][0];
pq.add(pairs[i][0]);
}
// score
long res = topK * pairs[k - 1][1];

// slide all possiblity
for(int i = k; i < n; i ++){
topK += pairs[i][0] - pq.poll();
pq.add(pairs[i][0]);

res = Math.max(res,topK * pairs[i][1]);
}
return res;
}
}