내용물
LeetCode 46. 풀 어레인지 (중)
[제목 설명]
중복된 숫자가 없는 배열이 주어지면 가능한 모든 순열을nums
반환합니다 . 어떤 순서로든 답변을 반환할 수 있습니다 .
【예시 1】
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
【예 2】
输入:nums = [0,1]
输出:[[0,1],[1,0]]
【예 3】
输入:nums = [1]
输出:[[1]]
【힌트】
1 ≤ 숫자 . 길이 ≤ 6 1\le nums.length\le 61≤번호 는 입니다 . _ 길이 _ _ _ _ _≤6
− 10 ≤ 숫자 [i ] ≤ 10 -10\le nums[i]\le 10- 10≤n u m s [ 나는 ]≤10
nums
의 모든 정수는서로 다릅니다.
【분석】
완전 배열형 네이키드 질문, DFS 입문 질문은 너무 많이 설명할 필요가 없습니다. 질문은 각 숫자가 서로 다르다는 것을 보장하므로 정수의 이진 시스템의 각 비트를 사용하여 특정 숫자가 다음과 같은지 여부를 나타낼 수 있습니다. 개방형 태그 배열에 대한 추가 공간 오버헤드를 생략하고 사용되었습니다.
물론, 즉시 죽이는 기능도 있지만 next_permutation
, 인터뷰하는 동안 손을 비비는 방법도 알아야 합니다~
【암호】
[ next_permutation
기능 구현 ]
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> permute(vector<int>& nums) {
sort(nums.begin(), nums.end());
do {
res.push_back(nums);
} while (next_permutation(nums.begin(), nums.end()));
return res;
}
};
[DFS 구현]
class Solution {
public:
vector<vector<int>> res;
vector<int> v;
vector<vector<int>> permute(vector<int>& nums) {
dfs(nums, 0, 0);
return res;
}
void dfs(vector<int>& nums, int u, int state) // state二进制的第i位表示i是否已被使用
{
if (u == nums.size()) {
res.push_back(v); return; }
for (int i = 0; i < nums.size(); i++)
if (!(state >> nums[i] + 10 & 1)) // 判断state的第i位是否为1,注意将nums[i]映射成0~20
{
v.push_back(nums[i]);
dfs(nums, u + 1, state | 1 << nums[i] + 10);
v.pop_back();
}
}
};
LeetCode 47. 풀 편곡 II (Medium)
[제목 설명]
반복되는 숫자를 포함할 수 있는 시퀀스가 있는 경우 , 반복되지 않는 모든 순열을 nums
순서에 관계없이 반환합니다.
【예시 1】
输入:nums = [1,1,2]
输出:[[1,1,2],[1,2,1],[2,1,1]]
【예 2】
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
【힌트】
1 ≤ 숫자 . 길이 ≤ 8 1\le nums.length\le 81≤번호 는 입니다 . _ 길이 _ _ _ _ _≤8
− 10 ≤ 숫자 [i ] ≤ 10 -10\le nums[i]\le 10- 10≤n u m s [ 나는 ]≤10
【분석】
이번 질문과 이전 질문의 차이점은 숫자가 반복될 수 있으므로 검색된 순서가 반복되지 않도록 제어하는 방법을 고려해야 합니다. 동일한 숫자에 대해 오름차순 또는 내림차순으로 정렬하는 등 순서를 지정하여 동일한 숫자의 배열이 하나의 대응 관계만 갖도록 해야 합니다.
이 작업을 수행하는 방법은 무엇입니까? 먼저 배열을 정렬하는데, 답안에서 같은 숫자의 상대 위치가 원래 배열과 동일한지 확인해야 하므로, 각 숫자를 열거할 때 와 가 사용되지 않으면 nums[i]
사용할 nums[i] == nums[i - 1]
수 nums[i - 1]
없습니다 nums[i]
. 이 질문에서는 state
바이너리 ii를 사용합니다.i 비트는nums[i]
사용 여부를 나타냅니다.
【암호】
class Solution {
public:
vector<vector<int>> res;
vector<int> v;
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end()); // 先排好序
dfs(nums, 0, 0);
return res;
}
void dfs(vector<int>& nums, int u, int state)
{
if (u == nums.size()) {
res.push_back(v); return; }
for (int i = 0; i < nums.size(); i++)
// 如果当前数和前一个数相等但是前一个数没被用过那么当前数也不能用
if (i && nums[i] == nums[i - 1] && !(state >> i - 1 & 1)) continue;
else if (!(state >> i & 1)) // 判断第i个数是否被使用
{
v.push_back(nums[i]);
dfs(nums, u + 1, state | 1 << i);
v.pop_back();
}
}
};
LeetCode 48. 이미지 회전(중간)
[제목 설명]
이미지를 나타내는 n × n
2차원 행렬이 주어졌습니다 . matrix
이미지를 시계방향으로 90도 회전시켜주세요. 이미지를 제자리
에서 회전해야 합니다 . 이는 입력 2D 매트릭스를 직접 수정해야 함을 의미합니다. 이미지를 회전하기 위해 다른 매트릭스를 사용하지 마십시오 .
【예시 1】
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]
【예 2】
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
【힌트】
n = = 행렬 . 길이 = = 행렬 [ i ] . 길이n == 행렬.길이 == 행렬[i].길이N==ma t r i x . 길이 _ _ _ _ _==ma t r i x [ i _ _ l e n g t h
1 ≤ n ≤ 20 1\and n\and1≤N≤20
− 1000 ≤ 행렬 [ i ] [ j ] ≤ 1000 -1000\le 행렬[i][j]\le 1000- 1000≤ma t r i x [ 나는 ] [ j ]≤1000
【분석】
먼저 변환 프로세스의 예를 들어보겠습니다.
1 2 3 1 4 7 7 4 1
4 5 6 => 2 5 8 => 8 5 2
7 8 9 3 6 9 9 6 3
과정은 매우 간단하지만 비슷한 문제에 노출되지 않았다면 알아내기가 정말 어렵습니다.먼저 주 대각선을 따라 뒤집은 다음 기둥의 중심축을 따라 뒤집습니다.
【암호】
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
// 沿对角线翻转
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
swap(matrix[i][j], matrix[j][i]);
// 沿列中轴线翻转
for (int i = 0; i < n; i++)
for (int j = 0; j < n >> 1; j++)
swap(matrix[i][j], matrix[i][n - 1 - j]);
}
};
LeetCode 49. 철자 바꾸기 그룹화(중간)
[제목 설명]
문자열 배열이 주어지고 철자 바꾸기를 함께 결합하라는 메시지가 표시됩니다. 결과 목록은 어떤 순서로든 반환될 수 있습니다.
철자 바꾸기는 원본 단어의 모든 문자를 재배열하여 얻은 새로운 단어입니다.
【예시 1】
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
【예 2】
输入: strs = [""]
输出: [[""]]
【예 3】
输入: strs = ["a"]
输出: [["a"]]
【힌트】
1 ≤ 문자열 . 길이 ≤ 1 0 4 1\le strs.length\le 10^41≤초 rs . _ 길이 _ _ _ _ _≤1 040
≤ 문자열 [i ] . 길이 ≤ 100 0\le strs[i].length\le 1000≤s t rs [ 나는 ] . 길이 _ _ _ _ _≤100
strs[i]
에는 소문자만 포함됩니다.
【분석】
각 문자열을 사전식 순서로 정렬할 수 있으므로 두 문자열에 동일한 문자가 포함되어 있으면 정렬된 문자열도 동일해야 하며 해시 테이블을 사용하여 각 문자열 유형을 기록할 수 있습니다.
【암호】
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
unordered_map<string, int> st; // 记录每一类的下标
int idx = 0;
for (auto s: strs)
{
string t = s;
sort(t.begin(), t.end());
if (!st[t]) st[t] = ++idx, res.push_back(vector<string> {
s });
else res[st[t] - 1].push_back(s); // 注意vector中下标从0开始
}
return res;
}
};
LeetCode 50. Pow(x, n) (중간)
[제목 설명]
구현 pow(x, n)
, 즉 x
정수 거듭 n
제곱 함수(예: xnx^n) 를 계산합니다.엑스n )。
【예시 1】
输入:x = 2.00000, n = 10
输出:1024.00000
【예 2】
输入:x = 2.10000, n = 3
输出:9.26100
【예 3】
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
【힌트】
– 100.0 < x < 100.0 -100.0 < x < 100.0- 100.0<엑스<100.0
− 2 31 ≤ n ≤ 2 31 − 1 -2^{31}\le n\le 2^{31}-1- 231≤N≤231-1
n
은0이 아닌 정수
이거나 입니다. − 10 4 ≤ xn ≤ 10 4 -10^4\le x^n\le 10^4x
n > 0
- 1 04≤엑스N≤1 04
【분석】
빠른 전력 문제, nn 통합n을 음수가 아닌 숫자로 변환한 후 풀고 마지막으로nn결과는 n 의 양수 및 음수 값으로 수정될 수 있습니다 (x − n = 1 xnx^{-n}=\frac {1}{x^n}엑스- n=엑스N1). nn 인 경우에 주의하세요.nINT_MIN
을 직접 양수로 변환하면 오버플로가 발생하므로 켜두어야합니다long long
.
【암호】
class Solution {
public:
double myPow(double x, int n) {
double res = 1;
for (long long k = abs((long long)n); k; k >>= 1)
{
if (k & 1) res *= x;
x *= x;
}
if (n < 0) res = 1 / res;
return res;
}
};