Skip to content

Commit

Permalink
Merge pull request #15 from VadimYarovoy/feat/linked_lists
Browse files Browse the repository at this point in the history
merge: Linked lists block
  • Loading branch information
VadimYarovoy authored Aug 17, 2024
2 parents b27085f + 1368bf0 commit 362bf0d
Show file tree
Hide file tree
Showing 11 changed files with 485 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod arrays;
mod linked_lists;
29 changes: 29 additions & 0 deletions src/linked_lists/doubly_linked_lists/leetcode_1472.rs
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()
}
}
189 changes: 189 additions & 0 deletions src/linked_lists/doubly_linked_lists/leetcode_707.rs
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;
}
}
}
}
}
2 changes: 2 additions & 0 deletions src/linked_lists/doubly_linked_lists/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod leetcode_1472;
mod leetcode_707;
3 changes: 3 additions & 0 deletions src/linked_lists/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod doubly_linked_lists;
mod queues;
mod singly_linked_lists;
48 changes: 48 additions & 0 deletions src/linked_lists/queues/leetcode_1700.rs
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
);
}
}
96 changes: 96 additions & 0 deletions src/linked_lists/queues/leetcode_255.rs
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()
}
}
2 changes: 2 additions & 0 deletions src/linked_lists/queues/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod leetcode_1700;
mod leetcode_255;
Loading

0 comments on commit 362bf0d

Please sign in to comment.