2023年8月——每日一题
1、8月6日 24. 两两交换链表中的节点
思路:直接模拟
使用虚拟头结点,初始时cur指向虚拟头结点,然后执行三步骤,具体见代码
C++代码
/**
* 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* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* cur = dummyHead;
while (cur && cur->next && cur->next->next) {
ListNode* node1 = cur->next;
ListNode* node2 = cur->next->next->next;
cur->next = cur->next->next;
cur->next->next = node1;
cur->next->next->next = node2;
cur = cur->next->next;
}
return dummyHead->next;
}
};
2、8月7日 344. 反转字符串
思路:双指针
C++代码
class Solution {
public:
void reverseString(vector<char>& s) {
int first = 0, last = s.size() - 1;
while (first < last) {
char temp = s[first];
s[first++] = s[last];
s[last--] = temp;
}
}
};
3、8月8日 1749. 任意子数组和的绝对值的最大值
思路:贪心
有两种情况可以得到和的绝对值最大值,一种情况是正和的最大值,另一种情况是负和的最小值。
(同7月20日每一题类似:918. 环形子数组的最大和)
- 情况一:通过
i
遍历nums
(可视为数组开头),count1
记录数组和(可以视为末尾),当count1<0
时,抛弃前面元素,count1
置为0,从i + 1
开始重新计算。 - 情况二:通过
i
遍历nums
(可视为数组开头),count2
记录数组和(可以视为末尾),当count2>0
时,抛弃前面元素,count1
置为0,从i + 1
开始重新计算。
最终返回正和最大值和负的负和最小值中的较大值。
C++代码
class Solution {
public:
int maxAbsoluteSum(vector<int>& nums) {
int res1 = INT_MIN;
int res2 = INT_MAX;
int count1 = 0;
int count2 = 0;
for (int i = 0; i < nums.size(); i++) {
count1 += nums[i];
res1 = max(res1, count1);
if (count1 < 0) count1 = 0;
count2 += nums[i];
res2 = min(res2, count2);
if (count2 > 0) count2 = 0;
}
return max(res1, -res2);
}
};
4、8月9日 1281. 整数的各位积和之差
思路:直接模拟
提取出n
的各个位的值,并求积和和,最后求差
C++代码
class Solution {
public:
int subtractProductAndSum(int n) {
int sum1 = 0, sum2 = 1;
while (n > 0) {
int temp = n % 10;
sum1 += temp;
sum2 *= temp;
n /= 10;
}
return sum2 - sum1;
}
};
5、8月10日 1289. 下降路径最小和 II
思路:动态规划
动态规划四步走:确定dp数组的下标及含义、确定递推公式、dp数组初始化、确定遍历顺序。
(和7月13日 931. 下降路径最小和类似)
- dp数组的下标及含义:
dp[i][j]
表示以grid[i][j]
为结尾的下降路径最小和 - 确定递推公式:
dp[i][j] = grid[i][j] + min(dp[i - 1][k])
,其中k不等于j - dp数组初始化:
dp[0][j] = grid[0][j]
- **确定遍历顺序:**从左到右,从上到下。
最后返回dp[dp.size() - 1][j]
的最小值即可。
C++代码
class Solution {
public:
int minFallingPathSum(vector<vector<int>>& grid) {
vector<vector<int>> dp(grid.size(), vector<int>(grid[0].size()));
for (int j = 0; j < dp[0].size(); j++) dp[0][j] = grid[0][j];
for (int i = 1; i < dp.size(); i++) {
for (int j = 0; j < dp[0].size(); j++) {
int temp = INT_MAX;
for (int k = 0; k < dp[0].size(); k++) {
if (j != k) temp = min(temp, dp[i - 1][k]);
}
dp[i][j] = grid[i][j] + temp;
}
}
int res = INT_MAX;
for (int j = 0; j < grid[0].size(); j++) res = min(res, dp[dp.size() - 1][j]);
return res;
}
};