-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from VadimYarovoy/feat/linked_lists
merge: Linked lists block
- Loading branch information
Showing
11 changed files
with
485 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
mod arrays; | ||
mod linked_lists; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#![allow(dead_code)] | ||
struct BrowserHistory { | ||
pos: usize, | ||
data: Vec<String>, | ||
} | ||
|
||
impl BrowserHistory { | ||
fn new(homepage: String) -> Self { | ||
Self { | ||
pos: 0, | ||
data: vec![homepage], | ||
} | ||
} | ||
|
||
fn visit(&mut self, url: String) { | ||
self.pos += 1; | ||
self.data.splice(self.pos.., std::iter::once(url)); | ||
} | ||
|
||
fn back(&mut self, steps: i32) -> String { | ||
self.pos = self.pos.saturating_sub(steps as usize); | ||
self.data[self.pos].clone() | ||
} | ||
|
||
fn forward(&mut self, steps: i32) -> String { | ||
self.pos = (self.pos + steps as usize).min(self.data.len() - 1); | ||
self.data[self.pos].clone() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
use std::{mem, ptr}; | ||
|
||
struct MyLinkedList { | ||
head: *mut MyNode, | ||
tail: *mut MyNode, | ||
len: i32, | ||
} | ||
|
||
impl Default for MyLinkedList { | ||
fn default() -> Self { | ||
Self { | ||
head: ptr::null_mut(), | ||
tail: ptr::null_mut(), | ||
len: 0, | ||
} | ||
} | ||
} | ||
|
||
impl Drop for MyLinkedList { | ||
fn drop(&mut self) { | ||
while self.len > 0 { | ||
self.delete_at_index(0); | ||
} | ||
} | ||
} | ||
|
||
struct MyNode { | ||
next: *mut MyNode, | ||
prev: *mut MyNode, | ||
val: i32, | ||
} | ||
|
||
impl MyNode { | ||
#[allow(dead_code)] | ||
fn new(val: i32) -> Self { | ||
Self { | ||
next: ptr::null_mut(), | ||
prev: ptr::null_mut(), | ||
val, | ||
} | ||
} | ||
} | ||
|
||
impl MyLinkedList { | ||
#[allow(dead_code)] | ||
fn new() -> Self { | ||
Self::default() | ||
} | ||
|
||
#[allow(dead_code)] | ||
fn get(&self, index: i32) -> i32 { | ||
if index >= self.len { | ||
return -1; | ||
} | ||
|
||
let mut target = self.head; | ||
|
||
unsafe { | ||
for _ in 0..index { | ||
target = (*target).next; | ||
} | ||
|
||
(*target).val | ||
} | ||
} | ||
|
||
#[allow(dead_code)] | ||
fn add_at_head(&mut self, val: i32) { | ||
let new_head = Box::into_raw(Box::new(MyNode::new(val))); | ||
let old_head = self.head; | ||
|
||
unsafe { | ||
if self.head.is_null() { | ||
self.head = new_head; | ||
self.tail = new_head; | ||
} else { | ||
(*old_head).prev = new_head; | ||
(*new_head).next = old_head; | ||
self.head = new_head; | ||
} | ||
} | ||
|
||
self.len += 1; | ||
} | ||
|
||
#[allow(dead_code)] | ||
fn add_at_tail(&mut self, val: i32) { | ||
let new_tail = Box::into_raw(Box::new(MyNode::new(val))); | ||
let old_tail = self.tail; | ||
|
||
unsafe { | ||
if self.tail.is_null() { | ||
self.head = new_tail; | ||
self.tail = new_tail; | ||
} else { | ||
(*old_tail).next = new_tail; | ||
(*new_tail).prev = old_tail; | ||
self.tail = new_tail; | ||
} | ||
} | ||
|
||
self.len += 1; | ||
} | ||
|
||
#[allow(dead_code)] | ||
fn add_at_index(&mut self, index: i32, val: i32) { | ||
match index { | ||
0 => { | ||
self.add_at_head(val); | ||
} | ||
index if index > self.len => {} | ||
index if index == self.len => { | ||
self.add_at_tail(val); | ||
} | ||
_ => { | ||
let new_mid = Box::into_raw(Box::new(MyNode::new(val))); | ||
let mut after = self.head; | ||
|
||
unsafe { | ||
for _ in 0..index { | ||
after = (*after).next; | ||
|
||
let prev = (*after).prev; | ||
(*prev).next = new_mid; | ||
(*new_mid).prev = prev; | ||
(*new_mid).next = after; | ||
(*after).prev = new_mid; | ||
} | ||
} | ||
|
||
self.len += 1; | ||
} | ||
} | ||
} | ||
|
||
fn delete_at_index(&mut self, index: i32) { | ||
match (index, self.len) { | ||
(index, len) if index >= len => {} | ||
(0, 1) => { | ||
let target = self.head; | ||
self.head = ptr::null_mut(); | ||
self.tail = ptr::null_mut(); | ||
|
||
unsafe { mem::drop(Box::from_raw(target)) } | ||
|
||
self.len -= 1; | ||
} | ||
(index, len) if index == len - 1 => unsafe { | ||
let target = self.tail; | ||
let prev = (*target).prev; | ||
self.tail = prev; | ||
(*prev).next = ptr::null_mut(); | ||
|
||
mem::drop(Box::from_raw(target)); | ||
|
||
self.len -= 1; | ||
}, | ||
(0, _) => unsafe { | ||
let target = self.head; | ||
let after = (*target).next; | ||
self.head = after; | ||
(*after).prev = ptr::null_mut(); | ||
|
||
mem::drop(Box::from_raw(target)); | ||
|
||
self.len -= 1; | ||
}, | ||
(index, _) => { | ||
let mut target = self.head; | ||
|
||
unsafe { | ||
for _ in 0..index { | ||
target = (*target).next; | ||
} | ||
|
||
let prev = (*target).prev; | ||
let after = (*target).next; | ||
|
||
(*prev).next = after; | ||
(*after).prev = prev; | ||
|
||
mem::drop(Box::from_raw(target)); | ||
|
||
self.len -= 1; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
mod leetcode_1472; | ||
mod leetcode_707; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mod doubly_linked_lists; | ||
mod queues; | ||
mod singly_linked_lists; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use std::collections::VecDeque; | ||
|
||
#[allow(dead_code)] | ||
fn count_students(students: Vec<i32>, sandwiches: Vec<i32>) -> i32 { | ||
let mut students: VecDeque<i32> = students.into(); | ||
|
||
let mut hungry = students.len() as i32; | ||
|
||
'outer: for sw in sandwiches { | ||
let curr_len = students.len(); | ||
let mut skiped = 0; | ||
|
||
loop { | ||
if curr_len < skiped || students.is_empty() { | ||
break 'outer; | ||
} | ||
if students[0] == sw { | ||
students.pop_front(); | ||
hungry -= 1; | ||
break; | ||
} else { | ||
let rounded = students.pop_front().unwrap(); | ||
students.push_back(rounded); | ||
skiped += 1; | ||
} | ||
} | ||
} | ||
|
||
hungry | ||
} | ||
|
||
#[cfg(test)] | ||
mod count_students_tests { | ||
use super::count_students; | ||
|
||
#[test] | ||
fn no_hungry() { | ||
assert_eq!(count_students(vec![1, 1, 0, 0], vec![0, 1, 0, 1]), 0); | ||
} | ||
|
||
#[test] | ||
fn some_hungry() { | ||
assert_eq!( | ||
count_students(vec![1, 1, 1, 0, 0, 1], vec![1, 0, 0, 0, 1, 1]), | ||
3 | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#![allow(dead_code)] | ||
use std::collections::VecDeque; | ||
|
||
struct MyStack { | ||
first: VecDeque<i32>, | ||
second: VecDeque<i32>, | ||
is_first: bool, | ||
} | ||
|
||
impl MyStack { | ||
fn new() -> Self { | ||
Self { | ||
first: Default::default(), | ||
second: Default::default(), | ||
is_first: true, | ||
} | ||
} | ||
|
||
fn push(&mut self, x: i32) { | ||
if self.is_first { | ||
self.first.push_back(x); | ||
} else { | ||
self.second.push_back(x); | ||
} | ||
} | ||
|
||
fn pop(&mut self) -> i32 { | ||
if self.is_first { | ||
let mut elem = None; | ||
|
||
for (idx, &el) in self.first.iter().enumerate() { | ||
if idx == self.first.len() - 1 { | ||
elem = Some(el); | ||
break; | ||
} | ||
self.second.push_back(el); | ||
} | ||
|
||
self.first.clear(); | ||
|
||
self.is_first = false; | ||
return elem.unwrap(); | ||
} else { | ||
let mut elem = None; | ||
|
||
for (idx, &el) in self.second.iter().enumerate() { | ||
if idx == self.second.len() - 1 { | ||
elem = Some(el); | ||
break; | ||
} | ||
self.first.push_back(el); | ||
} | ||
|
||
self.second.clear(); | ||
|
||
self.is_first = true; | ||
return elem.unwrap(); | ||
} | ||
} | ||
|
||
fn top(&mut self) -> i32 { | ||
if self.is_first { | ||
let mut elem = None; | ||
|
||
for (idx, &el) in self.first.iter().enumerate() { | ||
if idx == self.first.len() - 1 { | ||
elem = Some(el); | ||
} | ||
self.second.push_back(el); | ||
} | ||
|
||
self.first.clear(); | ||
|
||
self.is_first = false; | ||
return elem.unwrap(); | ||
} else { | ||
let mut elem = None; | ||
|
||
for (idx, &el) in self.second.iter().enumerate() { | ||
if idx == self.second.len() - 1 { | ||
elem = Some(el); | ||
} | ||
self.first.push_back(el); | ||
} | ||
|
||
self.second.clear(); | ||
|
||
self.is_first = true; | ||
return elem.unwrap(); | ||
} | ||
} | ||
|
||
fn empty(&self) -> bool { | ||
self.first.is_empty() && self.second.is_empty() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
mod leetcode_1700; | ||
mod leetcode_255; |
Oops, something went wrong.