1. 兩數之和
/**
* 給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返 * 回他們的數組下標。
* 你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個數組中同樣的元素。
* 示例:
* 給定 nums = [2, 7, 11, 15], target = 9
* 因爲 nums[0] + nums[1] = 2 + 7 = 9
* 所以返回 [0, 1]
*/
use std::collections::HashMap;
pub struct Solution {}
impl Solution {
pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
let mut map = HashMap::with_capacity(nums.len());
for (index, num) in nums.iter().enumerate() {
println!("index:{} num:{}", index, num);
match map.get(&(target - num)) {
None => {
map.insert(num, index);
}
Some(sub_index) => return vec![*sub_index as i32, index as i32],
}
}
vec![]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_0001_1() {
assert_eq!(vec![0, 1], Solution::two_sum(vec![2, 7, 11, 15], 9));
}
#[test]
fn test_0001_2() {
assert_eq!(vec![1, 3], Solution::two_sum(vec![2, 5, 8, 9, 13], 14));
}
#[test]
fn test_0001_3() {
assert_eq!(vec![0, 2], Solution::two_sum(vec![3, 2, 4], 6));
}
}
知識拾遺
https://doc.rust-lang.org/std/collections/struct.HashMap.html
哈希表(HashMap)是Rust內置的集合類型之一,屬於std::collections模塊下,它提供了一個平均複雜度爲O(1)的查詢方法。HashMap 的鍵可以是布爾型、整型、字符串,或任意實現了 Eq 和 Hash trait 的其他類型(要求所有的鍵必須是相同類型)和一個編譯時知道大小的Value類型,值也必須都是相同類型。 同時,Rust還要求你的Key類型必須是可比較的。HashMap 也是可增長的,但 HashMap 在空間多餘時能夠縮小自身。
- 創建 HashMap,可以使用適當的初始化容器(starting capacity) HashMap::with_capacity(unit),或者使用 HashMap::new() 來獲得一個帶有默認初始容器的 HashMap(推薦方式)。
- HashMap的數據是存儲在堆上。在Rust中,你可以爲你的類型輕易的加上編譯器屬性:
#[derive(PartialEq, Eq, Hash)]
HashMap的增刪改查
use std::collections::HashMap;
fn main() {
// 聲明
let mut hashmap_test = HashMap::new();
// 插入
hashmap_test.insert("key0", "value0");
hashmap_test.insert("key1", "value1");
hashmap_test.insert("key2", "value2");
hashmap_test.insert("key3", "value3");
println!("{:#?}", hashmap_test);
// 查找key
if !hashmap_test.contains_key("key5") {
println!(
"total {} keys in hashmap_test,but key5 not in it",
hashmap_test.len()
);
}
// 根據key刪除元素
hashmap_test.remove("key2");
println!("after remove key2:{:#?}", hashmap_test);
// 利用get的返回判斷元素是否存在
let keys = ["key0", "key4"];
for key in &keys {
match hashmap_test.get(key) {
Some(value) => println!("got key '{}' value is {}", key, value),
None => println!("{} not in hashmap_test", key),
}
}
// 遍歷輸出
for (key, value) in &hashmap_test {
println!("{}===>{}", key, value);
}
}
7. 整數反轉
/*
* 給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。
* 示例 1:
* 輸入: 123
* 輸出: 321
*
* 示例 2:
* 輸入: -123
* 輸出: -321
* 示例 3:
*
* 輸入: 120
* 輸出: 21
* 注意:
* 假設我們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 [−2^31, 2^31 − 1]。請根據這個假設,如果反轉後整數溢出那麼就返回 0。
*/
pub struct Solution {}
impl Solution {
pub fn reverse(x: i32) -> i32 {
let mut newx: i64 = x as i64;
let mut result: i64 = 0;
let mut digit: i64 = 0;
while newx != 0 {
digit = newx % 10;
result = result * 10 + digit;
newx = newx / 10;
}
println!("{:?}", result);
let base: i64 = 2;
let higher: i64 = base.pow(31) - 1;
let lower: i64 = -base.pow(31);
if result < lower || result > higher {
return 0;
}
return result as i32;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_0007_1() {
assert_eq!(321, Solution::reverse(123));
}
#[test]
fn test_0007_2() {
assert_eq!(-321, Solution::reverse(-123));
}
#[test]
fn test_0007_3() {
assert_eq!(21, Solution::reverse(120));
}
}
9. 迴文數
/*
* 判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。
*
* 示例 1:
* 輸入: 121
* 輸出: true
*
* 示例 2:
* 輸入: -121
* 輸出: false
* 解釋: 從左向右讀, 爲 -121 。 從右向左讀, 爲 121- 。因此它不是一個迴文數。
*
* 示例 3:
* 輸入: 10
* 輸出: false
* 解釋: 從右向左讀, 爲 01 。因此它不是一個迴文數。
*/
pub struct Solution {}
impl Solution {
pub fn is_palindrome(x: i32) -> bool {
if (x < 0) {
return false;
}
let mut newx = x;
let mut res = 0;
while newx != 0 {
let tmp = newx % 10;
res = res * 10 + tmp;
newx = newx / 10;
}
if res == x {
return true;
} else {
return false;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_0007_1() {
assert_eq!(true, Solution::is_palindrome(212));
}
#[test]
fn test_0007_2() {
assert_eq!(false, Solution::is_palindrome(-121));
}
#[test]
fn test_0007_3() {
assert_eq!(false, Solution::is_palindrome(120));
}
#[test]
fn test_0007_4() {
assert_eq!(true, Solution::is_palindrome(0));
}
}
9. 羅馬數字轉整數
/*
羅馬數字包含以下七種字符: I, V, X, L,C,D 和 M。
字符 數值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 羅馬數字 2 寫做 II ,即爲兩個並列的 1。12 寫做 XII ,即爲 X + II 。 27 寫做 XXVII, 即爲 XX + V + II 。
通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 4 不寫做 IIII,而是 IV。數字 1 在數字 5 的左邊,
所表示的數等於大數 5 減小數 1 得到的數值 4 。同樣地,數字 9 表示爲 IX。這個特殊的規則只適用於以下六種情況:
I 可以放在 V (5) 和 X (10) 的左邊,來表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左邊,來表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左邊,來表示 400 和 900。
給定一個羅馬數字,將其轉換成整數。輸入確保在 1 到 3999 的範圍內。
示例 1:
輸入: "III"
輸出: 3
示例 2:
輸入: "IV"
輸出: 4
示例 3:
輸入: "IX"
輸出: 9
示例 4:
輸入: "LVIII"
輸出: 58
解釋: L = 50, V= 5, III = 3.
示例 5:
輸入: "MCMXCIV"
輸出: 1994
解釋: M = 1000, CM = 900, XC = 90, IV = 4.
*/
use std::collections::HashMap;
pub struct Solution {}
impl Solution {
pub fn roman_to_int(s: String) -> i32 {
let map: HashMap<&str, i32> = [
("I", 1),
("V", 5),
("X", 10),
("L", 50),
("C", 100),
("D", 500),
("M", 1000),
]
.iter()
.cloned()
.collect();
let mut res: i32 = map[s.get(0..1).unwrap()];
let mut i = 1usize;
println!("{:?} s len {:?}", res, s.len());
while i < s.len() {
let key0 = s.get((i - 1)..i).unwrap();
let key1 = s.get(i..(i + 1)).unwrap();
if map[key0] < map[key1] {
res = res - 2 * map[key0] + map[key1];
} else {
res += map[key1];
}
i += 1;
}
res
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_0013() {
assert_eq!(Solution::roman_to_int("III".to_string()), 3);
assert_eq!(Solution::roman_to_int("IV".to_string()), 4);
assert_eq!(Solution::roman_to_int("IX".to_string()), 9);
assert_eq!(Solution::roman_to_int("MCMXCIV".to_string()), 1994);
assert_eq!(Solution::roman_to_int("DCXXI".to_string()), 621);
}
}