LeetCode 61. 旋转链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(!head) return head;
int n = 0;
ListNode *tail;
for(auto p = head; p; p = p -> next) {
tail = p;
n ++ ;
}
k %= n;
if(!k) return head;
auto p = head;
for(int i = 0; i < n - k - 1; i ++ ) p = p -> next;
tail -> next = head;
head = p -> next;
p -> next = nullptr;
return head;
}
};
LeetCode 62. 不同路径
状态表示:f[i, j]
表示机器人坐标共有几种路线可以走到坐标(i, j)
状态计算:f(i, 0) = 1
, f(0, j) = 1
f(i, j) = f(i - 1, j) + f(i, j - 1)
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> f(m, vector<int>(n, 0));
f[0][0] = 1;
for(int i = 0; i < n; i ++ ) f[0][i] = 1;
for(int i = 0; i < m; i ++ ) f[i][0] = 1;
for(int i = 1; i < m; i ++ )
for(int j = 1; j < n; j ++ )
f[i][j] = f[i - 1][j] + f[i][j - 1];
return f[m - 1][n - 1];
}
};
LeetCode 63. 不同路径 II
思路如LeetCode 62. 不同路径 ,不同点在于需要处理网格中的障碍物,如果网格中有障碍物,则将障碍物坐标对应的f(i,j)
赋值为0,再进行状态计算
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& a) {
if(a.empty()) return 0;
int n = a.size(), m = a[0].size();
vector<vector<int>> f(n, vector<int>(m, 0));
f[0][0] = 1;
int t = 1;
for(int i = 0; i < n; i ++ ) {
if(a[i][0] == 1) t = 0;
f[i][0] = t;
}
t = 1;
for(int i = 0; i < m; i ++ ) {
if(a[0][i] == 1) t = 0;
f[0][i] = t;
}
for(int i = 1; i < n; i ++ ) {
for(int j = 1; j < m; j ++ ) {
if(a[i][j] == 1) f[i][j] = 0;
else {
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
}
return f[n - 1][m - 1];
}
};
LeetCode 64. 最小路径和
状态表示: f(i, j)
表示走到坐标(i, j)
的最小路径和
状态计算:f(i, j) = a(i, j) + min(f(i - 1, j), f(i, j - 1))
class Solution {
public:
int minPathSum(vector<vector<int>>& f) {
int n = f.size(), m = f[0].size();
for(int i = 0; i < n; i ++ )
for(int j = 0; j < m; j ++ )
{
if(i == 0 && j == 0) continue;
else if(i == 0) f[i][j] += f[i][j - 1];
else if(j == 0) f[i][j] += f[i - 1][j];
else f[i][j] += min(f[i - 1][j], f[i][j - 1]);
}
return f[n - 1][m - 1];
}
};
LeetCode 65. 有效数字
模拟题,面向测试数据编程
class Solution {
public:
bool isNumber(string s) {
int l = 0, r = s.size() - 1;
while(l <= r && s[l] == ' ') l ++ ;
while(l <= r && s[r] == ' ') r -- ;
if(l > r) return false;
s.substr(l, r - l + 1);
if(s[0] == '+' || s[0] == '-' ) s = s.substr(1);
if(s.empty()) return false;
if(s[0] == '.' && (s.size() == 1 || s[1] == 'e' || s[1] == 'E'))
return false;
int dot = 0, e = 0;
for(int i = 0; i < s.size(); i ++ ) {
if(s[i] == '.') {
if(dot > 0 || e > 0) return false;
dot ++ ;
} else if(s[i] == 'e' || s[i] == 'E') {
if(!i || i + 1 == s.size() || e > 0) return false;
if(s[i + 1] == '+' || s[i + 1] == '-') {
if(i + 2 == s.size()) return false;
i ++ ;
}
e ++ ;
} else if(s[i] < '0' || s[i] > '9') return false;
}
return true;
}
};
LeetCode 66. 加一
思路类似高精度加法,使用变量t承载进位,每次计算使用t
与原有的数字进行相加,将t % 10
留在原地,每进一个位 t /= 10
class Solution {
public:
vector<int> plusOne(vector<int>& nums) {
int t = 0;
reverse(nums.begin(), nums.end());
nums[0] ++ ;
for(int i = 0; i < nums.size(); i ++ )
{
nums[i] += t;
t = nums[i] / 10;
nums[i] %= 10;
}
if(t) nums.push_back(1);
reverse(nums.begin(), nums.end());
return nums;
}
};
LeetCode 67. 二进制求和
类似高精度加法,将进制数字换成2即可
class Solution {
public:
string addBinary(string a, string b) {
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
string c;
for(int i = 0, t = 0; i < a.size() || i < b.size() || t; i ++ ) {
if(i < a.size()) t += a[i] - '0';
if(i < b.size()) t += b[i] - '0';
c += to_string(t % 2);
t /= 2;
}
reverse(c.begin(), c.end());
return c;
}
};
LeetCode 68. 文本左右对齐
- 先计算出当前行最多能放多少个单词,每个单词之间最少用一个空格隔开(通过双指针计算能放单词的总长度len)
- 假设当前行最多能放x个单词,需要满足下面3个条件进行放置
- 如果当前行是最后一行,则向左对齐(后面多余的用空格补上)
- 如果当前行只有一个单词,则向左对齐(后面多余的用空格补上)
- 其他情况均左右对齐
class Solution {
public:
vector<string> fullJustify(vector<string>& words, int maxWidth) {
vector<string> res;
for(int i = 0; i < words.size(); i ++ ) {
int j = i + 1;
int len = words[i].size();
while(j < words.size() && len + 1 + words[j].size() <= maxWidth)
len += 1 + words[j ++ ].size();
string line;
if(j == words.size() || j == i + 1) {
line += words[i];
for(int k = i + 1; k < j; k ++ ) line += ' ' + words[k];
while(line.size() < maxWidth) line += ' ';
} else {
int cnt = j - i - 1, r = maxWidth - len + cnt;
line += words[i];
int k = 0;
while(k < r % cnt) line += string(r / cnt + 1, ' ') + words[i + k + 1], k ++ ;
while(k < cnt) line += string(r / cnt, ' ') + words[i + k + 1], k ++ ;
}
res.push_back(line);
i = j - 1;
}
return res;
}
};
LeetCode 69. x 的平方根
二分法。
class Solution {
public:
int mySqrt(int x) {
if(x == 0) return 0;
if(x == 1) return 1;
int l = 1, r = x >> 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(mid > x / mid) r = mid - 1;
else l = mid;
}
return l;
}
};
LeetCode 70. 爬楼梯
斐波那契数列,也可以使用DP法进行分析
class Solution {
public:
int climbStairs(int n) {
if(n <= 1) return n;
long long a = 0, b = 1;
long long sum;
for(int i = 0; i <= n; i ++ )
{
sum = (a + b) % INT_MAX;
a = b, b = sum;
}
return a;
}
};