some more problems solved
This commit is contained in:
parent
6a5f3eccaf
commit
e028f4cf94
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
struct NumMatrix {
|
||||
sums_matrix: Vec<Vec<i32>>
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* `&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<Vec<i32>>) -> 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);
|
||||
*/
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
// TODO: Broken
|
||||
impl Solution {
|
||||
pub fn is_valid_sudoku(board: Vec<Vec<char>>) -> bool {
|
||||
let mut rows: HashMap<usize, HashSet<char>> = HashMap::new();
|
||||
let mut cols: HashMap<usize, HashSet<char>> = HashMap::new();
|
||||
let mut sqrs: HashMap<usize, HashSet<char>> = 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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// A more functional (and much worse imo) solution
|
||||
impl Solution {
|
||||
#[inline]
|
||||
pub fn contains_duplicate(row: &Vec<char>) -> 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<Vec<char>>) -> bool {
|
||||
!(
|
||||
board.iter() // Rows
|
||||
.any(|row| Solution::contains_duplicate(row)) ||
|
||||
(0..9).into_iter() // Columns
|
||||
.map(|idx| board.iter()
|
||||
.map(|row| row[idx])
|
||||
.collect::<Vec<char>>()
|
||||
)
|
||||
.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::<Vec<char>>()
|
||||
})
|
||||
.any(|row| Solution::contains_duplicate(&row))
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue