难度中等333
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2 输出: 4->5->1->2->3->NULL 解释: 向右旋转 1 步: 5->1->2->3->4->NULL 向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4 输出:2->0->1->NULL
解释: 向右旋转 1 步: 2->0->1->NULL 向右旋转 2 步: 1->2->0->NULL 向右旋转 3 步:0->1->2->NULL
向右旋转 4 步:2->0->1->NULL
软微题?
不过要冷静一些....注意情况啊
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(k==0||head==NULL) return head;
int cnt=0;//链表的长度
ListNode* tmp=head;
ListNode* last=head;
while(tmp!=NULL){
cnt++;
tmp=tmp->next;
if(cnt==1) continue;
last=last->next;
}
k=k%cnt;//就跟数组一样 0-cnt-1
if(k==0) return head;
//观察他们的改变
//0-1-2-NULL 2 -> 0-1 ->NUll
//1-2-3-4-5-NULL 4-5-> 1-2-3->NULL 需要修改两处
//所以需要记住第 cnt-k个 第cnt-k-1个
ListNode* node1;
ListNode* node2;
tmp=head;
node1=tmp->next;node2=tmp;
int m=cnt-k-1;
while(m--){
node1=node1->next;
node2=node2->next;
}
//修改
last->next=head;
node2->next=NULL;
return node1;
}
};
这样写就更好一些,因为有两个都是相邻的
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null || k == 0) return head;
int count = 1; // 用来统计链表总结点数
ListNode tmp = head;
while (tmp.next != null) {
count++;
tmp = tmp.next;
}
k %= count;
// 当k为0时,不需要旋转,
if (k == 0) return head;
// 不满足上述条件,必将进行旋转,所以先将首尾相连
tmp.next = head;
// 现在只需要找到倒数第k+1个节点
for (int i = 0; i < count - k; i++) {
tmp = tmp.next;
}
ListNode newHead = tmp.next;
tmp.next = null;
return newHead;
}
难度中等680
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
例如,上图是一个7 x 3 的网格。有多少可能的路径?
示例 1:
输入: m = 3, n = 2
输出: 3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右
示例 2:
输入: m = 7, n = 3
输出: 28
提示:
1 <= m, n <= 100
- 题目数据保证答案小于等于
2 * 10 ^ 9
class Solution {
public:
//其实是排列组合啦!
int uniquePaths(int m, int n){
vector<vector<int>> v(m+1,vector<int>(n+1,0));
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(i==1&&j==1) v[i][j]=1;
else if(i==1||j==1) v[i][j]=1;
else v[i][j]=v[i-1][j]+v[i][j-1];
}
}
return v[m][n];
}
};
class Solution {
public:
int uniquePaths(int m, int n) {
vector<int>dp(n, 1);
for(int i = 1; i < m; ++i) {
for(int j = 1; j < n; ++j) {
dp[j] += dp[j-1];
}
}
return dp[n-1];
}
};
难度中等408
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1
和 0
来表示。
说明:m 和 n 的值均不超过 100。
示例 1:
输入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2
条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m=obstacleGrid.size();
if(m==0) return 0;
int n=obstacleGrid[0].size();
vector<vector<int>> dp(m,vector<int>(n,0));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(obstacleGrid[i][j]==1){
dp[i][j]=0;continue;
}
else if(i==0&&j==0) dp[i][j]=1;
else if(i==0) dp[i][j]=dp[i][j-1];
else if(j==0) dp[i][j]=dp[i-1][j];
else dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int n = obstacleGrid.size(), m = obstacleGrid.at(0).size();
vector <int> f(m);
f[0] = (obstacleGrid[0][0] == 0);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (obstacleGrid[i][j] == 1) {
f[j] = 0;
continue;
}
if (j - 1 >= 0 && obstacleGrid[i][j - 1] == 0) {
f[j] += f[j - 1];
}
}
}
return f.back();
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/unique-paths-ii/solution/bu-tong-lu-jing-ii-by-leetcode-solution-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
难度中等667
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size();
int n=grid[0].size();
for(int i=0;i<m;i++){
for(int j =0;j<n;j++){
if(i==0&&j==0) continue;
if(i==0) grid[i][j]+=grid[i][j-1];
else if(j==0) grid[i][j]+=grid[i-1][j];
else grid[i][j]=min(grid[i-1][j],grid[i][j-1])+grid[i][j];
}
}
return grid[m-1][n-1];
}
};
65暂时跳
过
66. 加一
难度简单541给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
特解只有100000000哦
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n=digits.size();
if(n==0) return digits;
int carry=1;
for(int i=n-1;i>=0;i--){
digits[i]+=carry;
carry=digits[i]/10;
digits[i]%=10;
}
if(carry==0){
return digits;
}
vector<int> ans(n+1,0);
ans[0]=1;
return ans;//只可能是100000
}
};
难度简单469
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1
和 0
。
示例 1:
输入: a = "11", b = "1"
输出: "100"
示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
直接看答案
class Solution {
public String addBinary(String a, String b) {
StringBuilder ans = new StringBuilder();
int ca = 0;
for(int i = a.length() - 1, j = b.length() - 1;i >= 0 || j >= 0; i--, j--) {
int sum = ca;
sum += i >= 0 ? a.charAt(i) - '0' : 0;
sum += j >= 0 ? b.charAt(j) - '0' : 0;
ans.append(sum % 2);
ca = sum / 2;
}
ans.append(ca == 1 ? ca : "");
return ans.reverse().toString();
}
}
作者:guanpengchn
链接:https://leetcode-cn.com/problems/add-binary/solution/hua-jie-suan-fa-67-er-jin-zhi-qiu-he-by-guanpengch/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
68看起来好难咯
难度简单500
实现 int sqrt(int x)
函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
此题请拿二分练手/重写下哈
class Solution {
public:
int mySqrt(int x) {
int l = 0, r = x, ans = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if ((long long)mid * mid <= x) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return ans;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/sqrtx/solution/x-de-ping-fang-gen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
难度简单1229
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
class Solution {
public:
int climbStairs(int n) {
if(n==1) return 1;
if(n==2) return 2;
vector<int> v(n+1);
v[1]=1;
v[2]=2;
for(int i=3;i<=n;i++) v[i]=v[i-1]+v[i-2];
return v[n];
}
};class Solution {
public:
int climbStairs(int n) {
if(n==1) return 1;
if(n==2) return 2;
vector<int> v(n+1);
v[1]=1;
v[2]=2;
for(int i=3;i<=n;i++) v[i]=v[i-1]+v[i-2];
return v[n];
}
};