移动部分的题的实现

This commit is contained in:
游由 2022-02-18 14:21:26 +08:00
parent bf65cb603f
commit 03cfe2f5f6
10 changed files with 342 additions and 161 deletions

View File

@ -1,8 +1,12 @@
mod j1064;
mod m1721;
mod q0001;
mod q0002;
mod q0003;
mod q0006;
mod q0007;
mod q0008;
mod q0009;
mod q0012;
mod q0013;
mod q0021;

View File

@ -0,0 +1,58 @@
use crate::Solution;
impl Solution {
/// [1.两数之和](https://leetcode-cn.com/problems/two-sum/)
///
/// 2022-02-18 10:37:48
///
/// 给定一个整数数组 `nums` 和一个整数目标值 `target`,请你在该数组中找出 **和为目标值** _`target`_ 的那 **两个** 整数,并返回它们的数组下标。
///
/// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
///
/// 你可以按任意顺序返回答案。
///
/// + **示例 1**
/// + **输入:** nums = \[2,7,11,15\], target = 9
/// + **输出:** \[0,1\]
/// + **解释:** 因为 nums\[0\] + nums\[1\] == 9 ,返回 \[0, 1\] 。
/// + **示例 2**
/// + **输入:** nums = \[3,2,4\], target = 6
/// + **输出:** \[1,2\]
/// + **示例 3**
/// + **输入:** nums = \[3,3\], target = 6
/// + **输出:** \[0,1\]
/// + **提示:**
/// * `2 <= nums.length <= 104`
/// * `-109 <= nums[i] <= 109`
/// * `-109 <= target <= 109`
/// * **只会存在一个有效答案**
/// + **进阶:**你可以想出一个时间复杂度小于 `O(n2)` 的算法吗?
/// + Related Topics
/// * 数组
/// * 哈希表
/// * 👍 13449
/// * 👎 0
pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
let mut m = std::collections::HashMap::new();
for (i, v) in nums.into_iter().enumerate() {
if m.contains_key(&v) {
return vec![m[&v], i as i32];
}
m.insert(target - v, i as i32);
}
vec![]
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q0001() {
let nums = vec![2, 7, 11, 15];
let target = 9;
assert_eq!(Solution::two_sum(nums, target), vec![0, 1]);
}
}

View File

@ -0,0 +1,106 @@
use crate::Solution;
use crate::structure::ListNode;
impl Solution {
/// [2.两数相加](https://leetcode-cn.com/problems/add-two-numbers/)
///
/// 2022-02-18 10:56:18
///
/// 给你两个 **非空** 的链表,表示两个非负的整数。它们每位数字都是按照 **逆序** 的方式存储的,并且每个节点只能存储 **一位** 数字。
///
/// 请你将两个数相加,并以相同形式返回一个表示和的链表。
///
/// 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
///
/// + **示例 1**
/// + ![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2021/01/02/addtwonumber1.jpg)
/// + **输入:** l1 = \[2,4,3\], l2 = \[5,6,4\]
/// + **输出:** \[7,0,8\]
/// + **解释:** 342 + 465 = 807.
/// + **示例 2**
/// + **输入:** l1 = \[0\], l2 = \[0\]
/// + **输出:** \[0\]
/// + **示例 3**
/// + **输入:** l1 = \[9,9,9,9,9,9,9\], l2 = \[9,9,9,9\]
/// + **输出:** \[8,9,9,9,0,0,0,1\]
/// + **提示:**
/// * 每个链表中的节点数在范围 `[1, 100]` 内
/// * `0 <= Node.val <= 9`
/// * 题目数据保证列表表示的数字不含前导零
/// + Related Topics
/// * 递归
/// * 链表
/// * 数学
/// * 👍 7500
/// * 👎 0
pub fn add_two_numbers(mut l1: Option<Box<ListNode>>, mut l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut sum = 0;
let mut l = None;
let mut p = &mut l;
loop {
match (l1, l2) {
(Some(v1), Some(v2)) => {
sum += v1.val + v2.val;
l1 = v1.next;
l2 = v2.next;
}
(Some(v1), None) => {
sum += v1.val;
l1 = v1.next;
l2 = None;
}
(None, Some(v2)) => {
sum += v2.val;
l2 = v2.next;
l1 = None;
}
_ => {
break;
}
}
*p = Some(Box::new(ListNode::new(sum % 10))); //不管sum是否大于10都可以使用sum%10的值来构建新“节点“
sum /= 10; // 获取进位值否则初始为0
if let Some(p_box_node) = p {
p = &mut p_box_node.next
}
}
if sum != 0 {
*p = Some(Box::new(ListNode::new(sum)));
}
l
}
}
#[cfg(test)]
mod test {
use crate::Solution;
use crate::structure::ListNode;
#[test]
fn test_q0002() {
let l1 = Some(Box::new(ListNode {
val: 2,
next: Some(Box::new(ListNode {
val: 4,
next: Some(Box::new(ListNode::new(3))),
})),
}));
let l2 = Some(Box::new(ListNode {
val: 5,
next: Some(Box::new(ListNode {
val: 6,
next: Some(Box::new(ListNode::new(4))),
})),
}));
let ans = Some(Box::new(ListNode {
val: 7,
next: Some(Box::new(ListNode {
val: 0,
next: Some(Box::new(ListNode::new(8))),
})),
}));
assert_eq!(Solution::add_two_numbers(l1, l2), ans);
}
}

View File

@ -0,0 +1,82 @@
use crate::Solution;
impl Solution {
/// [6.Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/)
///
/// 2022-02-18 11:14:16
///
/// 将一个给定字符串 `s` 根据给定的行数 `numRows` ,以从上往下、从左到右进行 Z 字形排列。
///
/// 比如输入字符串为 `"PAYPALISHIRING"` 行数为 `3` 时,排列如下:
///
/// ``` txt
/// P A H N
/// A P L S I I G
/// Y I R
/// ```
///
/// 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:`"PAHNAPLSIIGYIR"`。
///
/// 请你实现这个将字符串进行指定行数变换的函数:
///
/// ``` c++
/// string convert(string s, int numRows);
/// ```
///
/// + **示例 1**
/// + **输入:** s = "PAYPALISHIRING", numRows = 3
/// + **输出:** "PAHNAPLSIIGYIR"
/// + **示例 2**
/// + **输入:** s = "PAYPALISHIRING", numRows = 4
/// + **输出:** "PINALSIGYAHRPI"
/// + **解释:**
/// ``` txt
/// P I N
/// A L S I G
/// Y A H R
/// P I
/// ```
/// + **示例 3**
/// + **输入:**s = "A", numRows = 1
/// + **输出:**"A"
/// + **提示:**
/// * `1 <= s.length <= 1000`
/// * `s` 由英文字母(小写和大写)、`','` 和 `'.'` 组成
/// * `1 <= numRows <= 1000`
/// + Related Topics
/// * 字符串
/// * 👍 1477
/// * 👎 0
pub fn convert(s: String, num_rows: i32) -> String {
if num_rows <= 1 {
return s;
}
let n = s.len();
let num_rows = num_rows as usize;
let cycle_len = 2 * num_rows - 2;
let s = s.into_bytes();
let mut ret = String::with_capacity(n);
for i in 0..num_rows {
let mut j = 0;
while j + i < n {
ret.push(s[i + j] as char);
if i != 0 && i != num_rows - 1 && j + cycle_len - i < n {
ret.push(s[j + cycle_len - i] as char);
}
j += cycle_len;
}
}
ret
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q0006() {
assert_eq!(Solution::convert("PAYPALISHIRING".to_string(), 3), "PAHNAPLSIIGYIR".to_string());
}
}

View File

@ -0,0 +1,86 @@
use crate::Solution;
impl Solution {
/// [9.回文数](https://leetcode-cn.com/problems/palindrome-number/)
///
/// 2022-02-18 14:04:23
///
/// 给你一个整数 `x` ,如果 `x` 是一个回文整数,返回 `true` ;否则,返回 `false` 。
///
/// 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
///
/// > 例如,`121` 是回文,而 `123` 不是。
///
/// + **示例 1**
/// + **输入:** x = 121
/// + **输出:** true
/// + **示例 2**
/// + **输入:** x = -121
/// + **输出:** false
/// + **解释:** 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
/// + **示例 3**
/// + **输入:** x = 10
/// + **输出:** false
/// + **解释:** 从右向左读, 为 01 。因此它不是一个回文数。
/// + **提示:**
/// * `-231 <= x <= 231 - 1`
/// + **进阶:**你能不将整数转为字符串来解决这个问题吗?
/// + Related Topics
/// * 数学
/// * 👍 1806
/// * 👎 0
///
/// 1. 方法1 字符串
/// ```rust
/// pub fn is_palindrome(x: i32) -> bool {
/// let xs = x.to_string().into_bytes();
/// let mut xsc = xs.clone();
/// xsc.reverse();
/// xs == xsc
/// }
/// ```
/// 2. 方法2 对数 双指针
/// ```rust
/// pub fn is_palindrome(mut x: i32) -> bool {
/// if x < 0 {
/// return false;
/// }
/// let exp = (x as f64).log10() as u32;
/// let mut n = 10i32.pow(exp);
/// while x > 0 {
/// let top = x / n;
/// if top != x % 10 {
/// return false;
/// }
/// x -= n * top;
/// x /= 10;
/// n /= 100;
/// }
/// true
/// }
/// ```
/// 3. 方法3 求一半逆序数
///
/// 实现见源码
pub fn is_palindrome(mut x: i32) -> bool {
if x < 0 || (x % 10 == 0 && x != 0) {
return false;
}
let mut r = 0;
while x > r {
r = r * 10 + x % 10;
x /= 10;
}
x == r || x == r / 10
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q0009() {
assert_eq!(Solution::is_palindrome(121), true);
}
}

View File

@ -74,6 +74,5 @@ mod test {
let mut nums = vec![1,1,1,2,2,3];
let a = Solution::remove_duplicates1(&mut nums);
assert_eq!(a, 5);
// unimplemented!()
}
}

View File

@ -62,7 +62,6 @@ impl Solution {
ret.extend(Solution::preorder_traversal(r.borrow_mut().right.take()));
}
ret
//unimplemented!()
/*let mut stack = vec![root];
let mut ret = vec![];
while let Some(n) = stack.pop() {

View File

@ -66,10 +66,14 @@ impl Solution {
#[cfg(test)]
mod test {
use crate::Solution;
use crate::structure::TreeNode;
use std::rc::Rc;
use std::cell::RefCell;
#[test]
fn test_q0872() {
let sq = 1;
// unimplemented!()
let root1 = Some(Rc::new(RefCell::new(TreeNode::new(3))));
let root2 = Some(Rc::new(RefCell::new(TreeNode::new(3))));
assert_eq!(Solution::leaf_similar(root1, root2), true);
}
}

View File

@ -48,7 +48,6 @@ impl Solution {
perm[i + 1] = perm[i] ^ encoded[i];
}
perm*/
//unimplemented!()
}
}

View File

@ -7,61 +7,6 @@ use std::rc::Rc;
use std::ops::Add;
impl Solution {
/// 1.两数之和
///
/// [原题链接](https://leetcode-cn.com/problems/two-sum/)
fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
let mut m = std::collections::HashMap::new();
for (i, v) in nums.into_iter().enumerate() {
if m.contains_key(&v) {
return vec![m[&v], i as i32];
}
m.insert(target - v, i as i32);
}
vec![]
}
/// 2.两数相加
///
/// [原题链接](https://leetcode-cn.com/problems/add-two-numbers/)
pub fn add_two_numbers(mut l1: Option<Box<ListNode>>, mut l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut sum = 0;
let mut l = None;
let mut p = &mut l;
loop {
match (l1, l2) {
(Some(v1), Some(v2)) => {
sum += v1.val + v2.val;
l1 = v1.next;
l2 = v2.next;
}
(Some(v1), None) => {
sum += v1.val;
l1 = v1.next;
l2 = None;
}
(None, Some(v2)) => {
sum += v2.val;
l2 = v2.next;
l1 = None;
}
_ => {
break;
}
}
*p = Some(Box::new(ListNode::new(sum % 10))); //不管sum是否大于10都可以使用sum%10的值来构建新“节点“
sum /= 10; // 获取进位值否则初始为0
if let Some(p_box_node) = p {
p = &mut p_box_node.next
}
}
if sum != 0 {
*p = Some(Box::new(ListNode::new(sum)));
}
l
}
/// 486.预测赢家
///
/// [原题链接](https://leetcode-cn.com/problems/predict-the-winner/)
@ -633,31 +578,6 @@ impl Solution {
solutions
}
/// 6.Z 字形变换
///
/// [原题链接](https://leetcode-cn.com/problems/zigzag-conversion/)
pub fn convert(s: String, num_rows: i32) -> String {
if num_rows <= 1 {
return s;
}
let n = s.len();
let num_rows = num_rows as usize;
let cycle_len = 2 * num_rows - 2;
let s = s.into_bytes();
let mut ret = String::with_capacity(n);
for i in 0..num_rows {
let mut j = 0;
while j + i < n {
ret.push(s[i + j] as char);
if i != 0 && i != num_rows - 1 && j + cycle_len - i < n {
ret.push(s[j + cycle_len - i] as char);
}
j += cycle_len;
}
}
ret
}
/// 36.有效的数独
///
/// [原题链接](https://leetcode-cn.com/problems/valid-sudoku/)
@ -1546,51 +1466,6 @@ impl Solution {
ans
}
/// 9.回文数
///
/// [原题链接](https://leetcode-cn.com/problems/palindrome-number/)
/// # 方法1 字符串
/// ```rust
/// pub fn is_palindrome(x: i32) -> bool {
/// let xs = x.to_string().into_bytes();
/// let mut xsc = xs.clone();
/// xsc.reverse();
/// xs == xsc
/// }
/// ```
/// # 方法2 对数 双指针
/// ```rust
/// pub fn is_palindrome(mut x: i32) -> bool {
/// if x < 0 {
/// return false;
/// }
/// let exp = (x as f64).log10() as u32;
/// let mut n = 10i32.pow(exp);
/// while x > 0 {
/// let top = x / n;
/// if top != x % 10 {
/// return false;
/// }
/// x -= n * top;
/// x /= 10;
/// n /= 100;
/// }
/// true
/// }
/// ```
/// # 方法3 求一半逆序数
pub fn is_palindrome(mut x: i32) -> bool {
if x < 0 || (x % 10 == 0 && x != 0) {
return false;
}
let mut r = 0;
while x > r {
r = r * 10 + x % 10;
x /= 10;
}
x == r || x == r / 10
}
/// 14.最长公共前缀
///
/// [原题链接](https://leetcode-cn.com/problems/longest-common-prefix/)
@ -1925,37 +1800,6 @@ impl Solution {
(stones.len() - count) as i32
}
/// 4.寻找两个正序数组的中位数
///
/// [原题链接](https://leetcode-cn.com/problems/median-of-two-sorted-arrays/)
/// # 方法1 暴力模拟法
/// ```rust
/// pub fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 {
/// let mut ret = 0.0;
/// let mut nums = Vec::new();
/// nums.extend(nums1);
/// nums.extend(nums2);
/// if nums.is_empty() {
/// return ret;
/// }
/// nums.sort();
/// if nums.len() & 1 == 0 {
/// ret = (nums[nums.len() / 2 - 1] as f64 + nums[nums.len() / 2] as f64) / 2.0;
/// } else {
/// ret = nums[nums.len() / 2] as f64;
/// }
/// ret
/// }
/// ```
pub fn find_median_sorted_arrays(nums1: Vec<i32>, nums2: Vec<i32>) -> f64 {
/*let t = nums1.len() + nums2.len();
let (mut i,mut j, k) = (0usize, 0usize, 0usize);
while i < nums1.len() || j < nums2.len() {
}*/
unimplemented!()
}
/// 11.盛最多水的容器
///
/// [原题链接](https://leetcode-cn.com/problems/container-with-most-water/)