From e028f4cf94aad8ebea6f39a125e2b0455f4f37b2 Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Sat, 4 Jun 2022 12:25:07 +0100 Subject: [PATCH] some more problems solved --- linked-list-cycle/sol.go | 26 +++++++++++++++ linked-list-cycle/sol_O(1)_mem.go | 28 ++++++++++++++++ merge-two-sorted-lists/sol.go | 33 +++++++++++++++++++ range-sum-query-2d-immutable/sol.rs | 41 +++++++++++++++++++++++ remove-linked-list-elements/sol_2.go | 31 ++++++++++++++++++ valid-sudoku/sol.go | 31 ++++++++++++++++++ valid-sudoku/sol.rs | 34 +++++++++++++++++++ valid-sudoku/sol_functional.rs | 49 ++++++++++++++++++++++++++++ 8 files changed, 273 insertions(+) create mode 100644 linked-list-cycle/sol.go create mode 100644 linked-list-cycle/sol_O(1)_mem.go create mode 100644 merge-two-sorted-lists/sol.go create mode 100644 range-sum-query-2d-immutable/sol.rs create mode 100644 remove-linked-list-elements/sol_2.go create mode 100644 valid-sudoku/sol.go create mode 100644 valid-sudoku/sol.rs create mode 100644 valid-sudoku/sol_functional.rs diff --git a/linked-list-cycle/sol.go b/linked-list-cycle/sol.go new file mode 100644 index 0000000..93836e8 --- /dev/null +++ b/linked-list-cycle/sol.go @@ -0,0 +1,26 @@ +package main + +type ListNode struct { + Val int + Next *ListNode +} + +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func hasCycle(head *ListNode) bool { + exists := map[*ListNode]bool{} + current := head + for current != nil { + exists[current] = true + current = current.Next + if exists[current] { + return true + } + } + return false +} diff --git a/linked-list-cycle/sol_O(1)_mem.go b/linked-list-cycle/sol_O(1)_mem.go new file mode 100644 index 0000000..bb5139f --- /dev/null +++ b/linked-list-cycle/sol_O(1)_mem.go @@ -0,0 +1,28 @@ +package main + +type ListNode struct { + Val int + Next *ListNode +} + +// This solution uses O(1) memory, but +// runtime duration is a bit more +// unpredictable with a maximum complexity +// of O(n^2) I think. +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func hasCycle(head *ListNode) bool { + slow, fast := head, head + for fast != nil && fast.Next != nil { + slow, fast = slow.Next, fast.Next.Next + if slow == fast { + return true + } + } + return false +} diff --git a/merge-two-sorted-lists/sol.go b/merge-two-sorted-lists/sol.go new file mode 100644 index 0000000..01fd5cc --- /dev/null +++ b/merge-two-sorted-lists/sol.go @@ -0,0 +1,33 @@ +package main + +type ListNode struct { + Val int + Next *ListNode +} + +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { + next1, next2 := list1, list2 + head := &ListNode{ + Val: -1, + Next: nil, + } + current := head + for next1 != nil || next2 != nil { + if next2 == nil || (next1 != nil && next1.Val < next2.Val) { + current.Next = next1 + next1 = next1.Next + } else { + current.Next = next2 + next2 = next2.Next + } + current = current.Next + } + return head.Next +} diff --git a/range-sum-query-2d-immutable/sol.rs b/range-sum-query-2d-immutable/sol.rs new file mode 100644 index 0000000..59b22dc --- /dev/null +++ b/range-sum-query-2d-immutable/sol.rs @@ -0,0 +1,41 @@ +struct NumMatrix { + sums_matrix: Vec> +} + + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl NumMatrix { + // Generate an accumulating sum matrix in-place + // O(1) extra memory + fn new(mut matrix: Vec>) -> Self { + for row in (0..matrix.len()) { + let mut acc = 0; + for col in (0..matrix[0].len()) { + acc += matrix[row][col]; + matrix[row][col] = acc; + if row != 0 { + matrix[row][col] += matrix[row-1][col]; + } + } + } + NumMatrix { sums_matrix: matrix } + } + + // Use the accumulating sums to get the sum of the region + // Space: O(1), Time: O(1) + fn sum_region(&self, row1: i32, col1: i32, row2: i32, col2: i32) -> i32 { + let top_rec = if row1 == 0 { 0 } else { self.sums_matrix[row1 as usize - 1][col2 as usize] }; + let left_rec = if col1 == 0 { 0 } else { self.sums_matrix[row2 as usize][col1 as usize - 1] }; + let rec_overlap = if row1 == 0 || col1 == 0 { 0 } else { self.sums_matrix[row1 as usize - 1][col1 as usize - 1] }; + self.sums_matrix[row2 as usize][col2 as usize] - top_rec - left_rec + rec_overlap + } +} + +/** + * Your NumMatrix object will be instantiated and called as such: + * let obj = NumMatrix::new(matrix); + * let ret_1: i32 = obj.sum_region(row1, col1, row2, col2); + */ \ No newline at end of file diff --git a/remove-linked-list-elements/sol_2.go b/remove-linked-list-elements/sol_2.go new file mode 100644 index 0000000..d4cd155 --- /dev/null +++ b/remove-linked-list-elements/sol_2.go @@ -0,0 +1,31 @@ +package main + +type ListNode struct { + Val int + Next *ListNode +} + +// Another solution I did because I accidentally +// did the question again from scratch +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func removeElements(head *ListNode, val int) *ListNode { + top_head := &ListNode{ + Val: -1, + Next: head, + } + current := top_head + for current != nil && current.Next != nil { + if current.Next.Val == val { + current.Next = current.Next.Next + } else { + current = current.Next + } + } + return top_head.Next +} diff --git a/valid-sudoku/sol.go b/valid-sudoku/sol.go new file mode 100644 index 0000000..f454669 --- /dev/null +++ b/valid-sudoku/sol.go @@ -0,0 +1,31 @@ +func isValidSudoku(board [][]byte) bool { + rows := make(map[int]map[byte]bool) + cols := make(map[int]map[byte]bool) + sqrs := make(map[int]map[byte]bool) + var cell byte + + for rowIdx := 0; rowIdx < 9; rowIdx++ { + rows[rowIdx] = make(map[byte]bool) + for colIdx := 0; colIdx < 9; colIdx++ { + if cols[colIdx] == nil{ + cols[colIdx] = make(map[byte]bool) + } + cell = board[rowIdx][colIdx] + if cell != '.' { + if rows[rowIdx][cell] || cols[colIdx][cell] { + return false + } + sqr := rowIdx - (rowIdx % 3) + colIdx / 3 + if sqrs[sqr] == nil { + sqrs[sqr] = make(map[byte]bool) + } + if sqrs[sqr][cell] { + return false + } + rows[rowIdx][cell], cols[colIdx][cell], sqrs[sqr][cell] = true, true, true + } + } + } + + return true +} \ No newline at end of file diff --git a/valid-sudoku/sol.rs b/valid-sudoku/sol.rs new file mode 100644 index 0000000..f1d3dd5 --- /dev/null +++ b/valid-sudoku/sol.rs @@ -0,0 +1,34 @@ +use std::collections::{HashMap, HashSet}; + +// TODO: Broken +impl Solution { + pub fn is_valid_sudoku(board: Vec>) -> bool { + let mut rows: HashMap> = HashMap::new(); + let mut cols: HashMap> = HashMap::new(); + let mut sqrs: HashMap> = HashMap::new(); + + for row in (0..9usize) { + rows.insert(row, HashSet::new()); + for col in (0..9usize) { + if !cols.contains_key(&col) { + cols.insert(col, HashSet::new()); + } + let cell = *board.get(row).unwrap().get(col).unwrap(); + if cell != '.' { + if !rows.get_mut(&row).unwrap().insert(cell) || !cols.get_mut(&row).unwrap().insert(cell) { + return false; + } + let sqr = row - (row % 3) + col / 3; + if !sqrs.contains_key(&sqr) { + sqrs.insert(sqr, HashSet::new()); + } + if !sqrs.get_mut(&sqr).unwrap().insert(cell) { + return false; + } + } + } + } + + true + } +} \ No newline at end of file diff --git a/valid-sudoku/sol_functional.rs b/valid-sudoku/sol_functional.rs new file mode 100644 index 0000000..d98a09b --- /dev/null +++ b/valid-sudoku/sol_functional.rs @@ -0,0 +1,49 @@ +// A more functional (and much worse imo) solution +impl Solution { + #[inline] + pub fn contains_duplicate(row: &Vec) -> bool { + let mut map = 0; + row + .iter() + .filter_map(|chr| { + if *chr != '.' { + return Some(1 << (*chr as usize - 49)); + } + None + }) + .any(|chr| { + if map & chr != 0 { + return true; + } + map |= chr; + false + }) + } + pub fn is_valid_sudoku(board: Vec>) -> bool { + !( + board.iter() // Rows + .any(|row| Solution::contains_duplicate(row)) || + (0..9).into_iter() // Columns + .map(|idx| board.iter() + .map(|row| row[idx]) + .collect::>() + ) + .any(|row| Solution::contains_duplicate(&row)) || + (0..9).into_iter() // 3 by 3 squares + .map(|idx| { + let (row_idx, col_idx) = (idx as usize / 3, idx as usize % 3); + board.iter() + .enumerate() + .filter_map(|(r, row)| { + if r / 3 == row_idx { + return Some(row[col_idx*3..(col_idx*3 + 3)].to_vec()); + } + None + }) + .flatten() + .collect::>() + }) + .any(|row| Solution::contains_duplicate(&row)) + ) + } +} \ No newline at end of file