Skip to main content

20 posts tagged with "weeklychallenge"

View All Tags

· One min read
Junhe Chen

Simple question using pq

class KthLargest {

PriorityQueue<Integer> pq = new PriorityQueue<>();
int k;
public KthLargest(int k, int[] nums) {
this.k = k;
for(int n : nums) pq.add(n);
while(pq.size() > k) pq.poll();
}

public int add(int val) {
pq.add(val);
if(pq.size() > k){
pq.poll();
}
return pq.peek();
}
}

/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/

· One min read
Junhe Chen
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// don't think quicksort is acutally good here
int[] res = new int[k];
HashMap<Integer,Integer> count = new HashMap<>();
for(int n : nums){
if(count.containsKey(n)){
count.put(n,count.get(n) + 1);
}else{
count.put(n,1);
}
}
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> {return b[1] - a[1];});
for(int key : count.keySet()){
pq.add(new int[]{key,count.get(key)});
}
for(int i = 0; i < k; i ++){
res[i] = pq.poll()[0];
}
return res;
}
}

· 2 min read
Junhe Chen
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
// to solve this question
// we first wanna to think this as a graph and using dfs find the path from a to b
// in order to do so ,
// we must construct a weighted graph
HashMap<String,HashMap<String,Double>> graph = new HashMap<>();

// we need to get equations to gain our two string node
// we also need to have a index to keep track
int index = 0;
for(List<String> e : equations){
String a = e.get(0);
String b = e.get(1);

graph.putIfAbsent(a,new HashMap<>());
graph.putIfAbsent(b,new HashMap<>());


graph.get(a).put(b,values[index]);
graph.get(b).put(a,1 / values[index]);
index ++;

graph.get(a).put(a,1.0);
graph.get(b).put(b,1.0);

}
// we have sucessfully build our graph
// lets look at our queiries
double [] ans = new double[queries.size()];
Arrays.fill(ans,-1.0);
for(int i = 0; i < queries.size(); i ++){
List<String> q = queries.get(i);
String start = q.get(0);
String end = q.get(1);

// check if start and end in the graph at all
if(!graph.containsKey(start) || !graph.containsKey(end)){
continue;
}else {
dfs(graph,start,end,new HashSet<String>(),1.0,ans,i);

continue;
}
}
return ans;
}
// let's make our dfs method
private void dfs (HashMap<String,HashMap<String,Double>> graph, String start, String end, Set<String> visited, double pre, double[] ans, int index){
visited.add(start);
if(graph.get(start).containsKey(end)){
ans[index] = graph.get(start).get(end) * pre;
}

for(String next : graph.get(start).keySet()){
if (visited.contains(next)) continue;
dfs(graph,next,end,visited,graph.get(start).get(next) * pre ,ans,index);
}
}
}

· One min read
Junhe Chen

Simple graph coloring question.

class Solution {
public boolean isBipartite(int[][] graph) {
// graph color
int n = graph.length;
int[] color = new int[n];
Arrays.fill(color, -1);

for(int i = 0; i < n; i ++){
if(color[i] == -1){
if(!isBipartite(graph,i,color)){
return false;
}
}
}
return true;
}
private boolean isBipartite(int[][] graph, int curr, int[] color){
Queue<Integer> q = new LinkedList<>();
color[curr] = 1; // color curr node to 1
q.add(curr);
while(!q.isEmpty()){
int c = q.poll();
for(int next : graph[c]){
if(color[next] == color[c]) return false;
if(color[next] == -1){
// this is not colored yet
color[next] = 1 - color[c];
q.add(next);
}
}
}
return true;
}
}

· One min read
Junhe Chen

This is a tropological sort kind of problem, we can't use union find because we would union things all together. Instead, we should just care about nodes that aren't reachable from other nodes.

class Solution {
public List<Integer> findSmallestSetOfVertices(int n, List<List<Integer>> edges) {
boolean[] pointed = new boolean[n];
for(List<Integer> edge : edges){
pointed[edge.get(1)] = true; // this node can be reached from other nodes
}
List<Integer> res = new ArrayList<>();
for(int i = 0; i < n; i ++){
// any nodes cant be reached from other nodes we just add into res
if(!pointed[i]) res.add(i);
}
return res;
}
}

· One min read
Junhe Chen

This involves going to middle, reverse second half and then pair them up two pass apporach with extra memory would be using stack

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public int pairSum(ListNode head) {
ListNode slow = head;
ListNode fast = head;
// Get middle of the linked list.
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// Reverse second half of the linked list.
ListNode nextNode, prev = null;
while (slow != null) {
nextNode = slow.next;
slow.next = prev;
prev = slow;
slow = nextNode;
}
ListNode start = head;
int maximumSum = 0;
while (prev != null) {
maximumSum = Math.max(maximumSum, start.val + prev.val);
prev = prev.next;
start = start.next;
}

return maximumSum;
}
}

· One min read
Junhe Chen

Little busy, but this is just as much a problem as reverse linkedlist.

class Solution {
public ListNode swapPairs(ListNode head) {
// base case
if(head == null || head.next == null) return head;
ListNode last = head.next; // this would be the new head, because we have to reverse curr and next
head.next = swapPairs(head.next.next); // the head is now the curr sections last node and it suppose to connect to the rest of the list
last.next = head; // set the new head to connect to the curr head which is tail of the curr section
return last;
}
}

· 2 min read
Junhe Chen

this is a two pointer question, it uses slow fast pointer technique to get pointer to the kth node from the end, then find the front node !!

class Solution {
public ListNode swapNodes(ListNode head, int k) {
// locate the end node
ListNode slow = head;
ListNode fast = head;
int k1 = k;
while(fast != null && k1 > 0){
fast = fast.next;
k1 --;
}
while(fast != null){
slow = slow.next;
fast = fast.next;
}
ListNode p = head;
while(p != null && k > 1){
p = p.next;
k --;
}
// make the swap
int temp = p.val;
p.val = slow.val;
slow.val = temp;
return head;
}
}

265. Paint House II

This is a classic dp problem, but also little like advance graph apporach! Be sure to review this problem again tomorrow!

class Solution {
public int minCostII(int[][] costs) {
if(costs.length == 0) return 0; // nothing to paint
int k = costs[0].length; // the k color we are looking for
int n = costs.length;
int[] previousRow = costs[0];

for(int house = 1; house < n; house++){
// we going to look at curr costs
int[] currRow = new int[k];
for(int color = 0; color < k; color ++){
int min = Integer.MAX_VALUE;
// locate the cheapest solution from last row, we want the cheapest cost so far
for(int previousColor = 0; previousColor < k; previousColor ++){
if(color == previousColor){
// we can't print two adjusent color same
continue;
}
min = Math.min(min, previousRow[previousColor]);
}
// if we would paint curr house curr color, then we add cost from min previous house and cost of curr house
currRow[color] += costs[house][color] += min;
}
// now we want to change previousRow = curr
previousRow = currRow;
}
// now we have the final row, find return the res
int res = Integer.MAX_VALUE;
for(int cost : previousRow){
res = Math.min(res,cost);
}
return res;
}
}

· 2 min read
Junhe Chen

The dp part of the problem is not hard, but mask is difficult, and that is what we have to take a closer look to. I need to review this question tmr again.

class Solution {
int[] memo;
public int maxScore(int[] nums) {
memo = new int[ 1 << nums.length];
Arrays.fill(memo,-1);
return dp(nums, 0, 0);
}
private int dp(int[] nums, int mask, int pairsPicked){
// base case
if(2 * pairsPicked == nums.length) return 0; // we picked all number
// solved case
if(memo[mask] != -1) return memo[mask];

int max = 0;
for(int i = 0; i < nums.length; i ++){
for(int j = i + 1; j < nums.length; j ++){
// If the numbers are same, or already picked, then we move to next number.
if (((mask >> i) & 1) == 1 || ((mask >> j) & 1) == 1) {
continue;
}

// Both numbers are marked as picked in this new mask.
int newMask = mask | (1 << i) | (1 << j);
// Calculate score of current pair of numbers, and the remaining array.
int currScore = (pairsPicked + 1) * gcd(nums[i], nums[j]);
int remainingScore = dp(nums, newMask, pairsPicked + 1);

// Store the maximum score.
max = Math.max(max, currScore + remainingScore);
// We will use old mask in loop's next interation,
// means we discarded the picked number and backtracked.
}
}
return memo[mask] = max;
}
private int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
}

· 2 min read
Junhe Chen

This question interesting because our dp is not finding the min of the length but it is finding the ending index of given starting point p1. This is a very new DP problem that I have first encountered.

class Solution {
Integer[][] memo;
int min = Integer.MAX_VALUE;
int start = -1;
public String minWindow(String s1, String s2) {
memo = new Integer[s1.length()][s2.length() + 1];
dp(s1,s2,0,0);
return start == -1 ? "" : s1.substring(start,start + min);
}
private int dp(String s1, String s2, int p1, int p2){
// we use dp method to find the ending index at given index of s1

if(p2 == s2.length()) return p1; // we have all the character from p2
if(p1 == s1.length()) return Integer.MAX_VALUE; // we are not able to match
// solved case
if(memo[p1][p2] != null) return memo[p1][p2];
// solve the case
// starts with skip the character
int res = dp(s1,s2,p1 + 1, p2);
if(s1.charAt(p1) == s2.charAt(p2)){
// we have a match
res = Math.min(res,dp(s1,s2,p1 + 1, p2 + 1));
}
if(p2 == 0 && res < Integer.MAX_VALUE){
// this is a valid starting point
// note since we called skip first, that means we are always replacing the substring as we moving forward
// so res - p1 <= min is important here to locate the correct starting point
if(res - p1 <= min){
min = res - p1;
start = p1;
}
}
return memo[p1][p2] = res;
}

}