-
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.
- Loading branch information
0 parents
commit 2f68211
Showing
27 changed files
with
957 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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Project exclude paths | ||
/cmake-build-debug/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,23 @@ | ||
cmake_minimum_required(VERSION 3.24) | ||
project(coding-interviews-cpp) | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
aux_source_directory( | ||
src/chapter-2 | ||
CHAPTER_2 | ||
) | ||
|
||
aux_source_directory( | ||
src/chapter-3 | ||
CHAPTER_3 | ||
) | ||
|
||
aux_source_directory( | ||
src/data-structure | ||
DS | ||
) | ||
|
||
include_directories(src/include) | ||
|
||
add_executable(coding-interviews-cpp src/main.cpp ${CHAPTER_2} ${CHAPTER_3} ${DS}) |
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,50 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 10-1. 斐波那契数列 | ||
* 写一个函数,输入 n ,求斐波那契 (Fibonacci) 数列的第 n 项(即 F(N))。 | ||
*/ | ||
|
||
int solution::GetFibonacciItem(int n) { | ||
constexpr int result[2] = {0, 1}; | ||
if (n < 2) { | ||
return result[n]; | ||
} | ||
|
||
int fibN = 0; | ||
int fibNMinusOne = 1; | ||
int fibNMinusTwo = 0; | ||
|
||
for (int i = 2; i <= n; ++i) { | ||
fibN = (fibNMinusOne + fibNMinusTwo) % 1000000007; | ||
fibNMinusTwo = fibNMinusOne; | ||
fibNMinusOne = fibN; | ||
} | ||
|
||
return fibN; | ||
} | ||
|
||
/* | ||
* 10-2. 青蛙跳台阶问题 | ||
* 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法。 | ||
* 答案需要取模1e9+7(1000000007),如计算初始结果为:1000000008,请返回1。 | ||
*/ | ||
|
||
int solution::NumWays(int n) { | ||
constexpr int result[2] = {1, 1}; | ||
if (n < 2) { | ||
return result[n]; | ||
} | ||
|
||
int fibN = 0; | ||
int fibNMinusOne = 1; | ||
int fibNMinusTwo = 1; | ||
|
||
for (int i = 2; i <= n; ++i) { | ||
fibN = (fibNMinusOne + fibNMinusTwo) % 1000000007; | ||
fibNMinusTwo = fibNMinusOne; | ||
fibNMinusOne = fibN; | ||
} | ||
|
||
return fibN; | ||
} |
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 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 11. 旋转数组的最小数字 | ||
* 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 | ||
* 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。 | ||
* 请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为1。 | ||
*/ | ||
|
||
int solution::GetMinInRotatedArray(vector<int>& numbers) { | ||
int index1 = 0; | ||
int index2 = numbers.size() - 1; | ||
int indexMid = index1; | ||
|
||
auto GetMinInOrder = [numbers]() -> int { | ||
int min = INT32_MAX; | ||
for (const int num: numbers) { | ||
if (num < min) { | ||
min = num; | ||
} | ||
} | ||
return min; | ||
}; | ||
|
||
while (numbers[index1] >= numbers[index2]) { | ||
// 跳出条件 | ||
if (index2 - index1 == 1) { | ||
indexMid = index2; | ||
break; | ||
} | ||
|
||
indexMid = (index1 + index2) / 2; | ||
|
||
// 若无法比较,则按照顺序查找 | ||
if (numbers[index1] == numbers[index2] && numbers[index1] == numbers[indexMid]) { | ||
return GetMinInOrder(); | ||
} | ||
|
||
// 迭代中间元素 | ||
if (numbers[index1] <= numbers[indexMid]) { | ||
index1 = indexMid; | ||
} else if (numbers[index2] >= numbers[indexMid]) { | ||
index2 = indexMid; | ||
} | ||
} | ||
|
||
return numbers[indexMid]; | ||
} |
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,62 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 12. 矩阵中的路径 | ||
* 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true;否则,返回 false。 | ||
* 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。 | ||
* 同一个单元格内的字母不允许被重复使用。 | ||
*/ | ||
|
||
bool solution::ExistWordInMatrix(vector<vector<char>>& board, string word) { | ||
if (board.empty()) { | ||
return false; | ||
} | ||
|
||
const int rows = board.size(); | ||
const int cols = board[0].size(); | ||
int pathLength = 0; | ||
|
||
bool** visited = new bool* [rows]; | ||
for (int i = 0; i < rows; ++i) { | ||
visited[i] = new bool[cols]; | ||
std::fill(visited[i], visited[i] + cols + 1, false); | ||
} | ||
|
||
for (int i = 0; i < rows; ++i) { | ||
for (int j = 0; j < cols; ++j) { | ||
if (HasPath(board, word, i, j, pathLength, visited)) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
delete[] visited; | ||
return false; | ||
} | ||
|
||
bool solution::HasPath(vector<vector<char>>& board, string word, int row, int col, int& pathLength, bool**& visited) { | ||
if (pathLength == word.length()) { | ||
return true; | ||
} | ||
|
||
bool hasPath = false; | ||
|
||
if ((row >= 0 && row < board.size()) && (col >= 0 && col < board[0].size()) | ||
&& board[row][col] == word[pathLength] | ||
&& !visited[row][col]) { | ||
++pathLength; | ||
visited[row][col] = true; | ||
|
||
hasPath = HasPath(board, word, row + 1, col, pathLength, visited) || | ||
HasPath(board, word, row, col + 1, pathLength, visited) || | ||
HasPath(board, word, row - 1, col, pathLength, visited) || | ||
HasPath(board, word, row, col - 1, pathLength, visited); | ||
|
||
if (!hasPath) { | ||
--pathLength; | ||
visited[row][col] = false; | ||
} | ||
} | ||
|
||
return hasPath; | ||
} |
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,60 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 13. 机器人的运动范围 | ||
* 地上有一个m行n列的方格。一个机器人从坐标(0, 0)的格子开始移动, | ||
* 它每次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。 | ||
*/ | ||
|
||
int solution::MovingCount(int m, int n, int k) { | ||
if (m <= 0 || n <= 0 || k < 0) { | ||
return 0; | ||
} | ||
|
||
bool** visited = new bool* [m]; | ||
for (int i = 0; i < m; ++i) { | ||
visited[i] = new bool[n]; | ||
std::fill(visited[i], visited[i] + n, false); | ||
} | ||
|
||
int count = MovingCountCore(m, n, k, 0, 0, visited); | ||
for (int i = 0; i < m; ++i) { | ||
delete[] visited[i]; | ||
} | ||
delete[] visited; | ||
|
||
return count; | ||
} | ||
|
||
int solution::MovingCountCore(int m, int n, int k, int row, int col, bool** visited) { | ||
int count = 0; | ||
if (IsReached(m, n, k, row, col, visited)) { | ||
visited[row][col] = true; | ||
|
||
count = 1 + MovingCountCore(m, n, k, row + 1, col, visited) | ||
+ MovingCountCore(m, n, k, row, col + 1, visited) | ||
+ MovingCountCore(m, n, k, row - 1, col, visited) | ||
+ MovingCountCore(m, n, k, row, col - 1, visited); | ||
} | ||
|
||
return count; | ||
} | ||
|
||
bool solution::IsReached(int m, int n, int k, int row, int col, bool** visited) { | ||
if ((row >= 0 && row < m) && (col >= 0 && col < n) | ||
&& !visited[row][col] | ||
&& GetDigitSum(row) + GetDigitSum(col) <= k) { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
int solution::GetDigitSum(int num) { | ||
int sum = 0; | ||
while (num > 0) { | ||
sum += num % 10; | ||
num /= 10; | ||
} | ||
return sum; | ||
} |
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,73 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 14-1. 剪绳子-I | ||
* 给你一根长度为n的绳子,请把绳子剪成整数长度的m段(m、n都是整数,n>1并且m>1), | ||
* 每段绳子的长度记为k[0],k[1]...k[m-1]。请问k[0]*k[1]*...*k[m-1]可能的 | ||
* 最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时 | ||
* 得到的最大乘积是18。 | ||
*/ | ||
|
||
int solution::CuttingRope_DP(int n) { | ||
if (n <= 1) return 0; | ||
if (n == 2) return 1; | ||
if (n == 3) return 2; | ||
|
||
vector<int> products = {0, 1, 2, 3}; | ||
products.resize(n + 1); | ||
|
||
int maxProduct; | ||
for (int i = 4; i <= n; ++i) { | ||
maxProduct = 0; | ||
for (int j = 1; j <= i / 2; ++j) { | ||
int product = products[j] * products[i - j]; | ||
if (maxProduct < product) { | ||
maxProduct = product; | ||
} | ||
products[i] = maxProduct; | ||
} | ||
} | ||
|
||
maxProduct = products[n]; | ||
return maxProduct; | ||
} | ||
|
||
|
||
/* | ||
* 14-2. 剪绳子-II | ||
* 给你一根长度为n的绳子,请把绳子剪成整数长度的m段(m、n都是整数,n>1并且m>1), | ||
* 每段绳子的长度记为k[0],k[1]...k[m - 1] 。请问 k[0]*k[1]*...*k[m - 1] | ||
* 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段, | ||
* 此时得到的最大乘积是18。答案需要取模 e9+7(1000000007,如计算初始结果为:1000000008,请返回 1。 | ||
*/ | ||
|
||
int solution::CuttingRope_GD(int n) { | ||
if (n <= 1) return 0; | ||
if (n == 2) return 1; | ||
if (n == 3) return 2; | ||
|
||
int timesOf3 = n / 3; | ||
if (n - timesOf3 * 3 == 1) --timesOf3; | ||
int timesOf2 = (n - timesOf3 * 3) / 2; | ||
|
||
long long result = | ||
(FastPowerRemainder(3, timesOf3, 1000000007) * FastPowerRemainder(2, timesOf2, 1000000007)) % 1000000007; | ||
return static_cast<int>(result); | ||
} | ||
|
||
long long solution::FastPowerRemainder(int x, int a, int p) { | ||
long long remainder = 1; | ||
long long base = x; | ||
long long exp = a; | ||
long long divisor = p; | ||
|
||
while (exp > 0) { | ||
if (exp % 2 == 1) { | ||
remainder = (remainder * base) % divisor; | ||
} | ||
base = (base * base) % divisor; | ||
exp /= 2; | ||
} | ||
|
||
return remainder; | ||
} |
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,17 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 15. 二进制中1的个数 | ||
* 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为'1'的个数(也被称为 汉明重量).)。 | ||
*/ | ||
|
||
int solution::GetNumberOf1B(uint32_t n) { | ||
int count = 0; | ||
|
||
while (n) { | ||
++count; | ||
n = (n - 1) & n; | ||
} | ||
|
||
return count; | ||
} |
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,35 @@ | ||
#include "solution.h" | ||
|
||
/* | ||
* 03. 数组中重复的数字 | ||
* 在一个长度为n的数组 nums 里的所有数字都在0~n-1的范围内。 | ||
* 数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 | ||
*/ | ||
|
||
int solution::FindRepeatNumber(vector<int>& nums) { | ||
const int length = nums.size(); | ||
|
||
if (length == 0) { | ||
return false; | ||
} | ||
|
||
for (int i = 0; i < length; ++i) { | ||
if (nums[i] < 0 || nums[i] > length - 1) { | ||
return false; | ||
} | ||
} | ||
|
||
for (int i = 0; i < length; ++i) { | ||
while (nums[i] != i) { | ||
int& value = nums[i]; | ||
|
||
if (nums[value] == value) { | ||
return value; | ||
} | ||
|
||
std::swap(value, nums[value]); | ||
} | ||
} | ||
|
||
return -1; | ||
} |
Oops, something went wrong.