最后一个单词的长度:
思路:跳过末尾的空格,可以从后向前遍历
然后再利用 while(i>=0 && s[i] != ' ') 可以得到字符串的长度,
int lengthOfLastWord(char* s) {
int length = 0;
int i = strlen(s) - 1; //从字符串末尾开始
//跳过末尾的空格:
while(i>=0 && s[i] == ' '){
i--;
}
while(i>=0 && s[i] != ' '){
i--;
length++;
}
return length;
}
加一:
示例 1:
输入:digits = [1,2,3] 输出:[1,2,4] 解释:输入数组表示数字 123。示例 2:
输入:digits = [4,3,2,1] 输出:[4,3,2,2] 解释:输入数组表示数字 4321。示例 3:
输入:digits = [9] 输出:[1,0] 解释:输入数组表示数字 9。 加 1 得到了 9 + 1 = 10。 因此,结果应该是 [1,0]。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* plusOne(int* digits, int digitsSize, int* returnSize) {
//从末尾开始处理,模拟加一操作
int carry = 1;
//创建一个新数组,用于存放加一后的结果
int* result = (int*)malloc(sizeof(int) * (digitsSize + 1));
//从后向前遍历:
// 0 1 2 3 4
//eg 4 2 9 9
//eg 4 3 0 0
for(int i = digitsSize - 1; i >= 0;i--){
int sum = digits[i] + carry;
result[i + 1] = sum % 10;
carry = sum / 10; //计算新的进位
}
//如果处理完仍有进位
if(carry){
result[0] = carry; //
*returnSize = digitsSize + 1; //返回的数组大小增加1
}else{
for(int i = 0;i < digitsSize;i++){
result[i] = result[i + 1];
}
*returnSize = digitsSize;
}
return result;
}
二进制求和:
示例 1:
输入:a = "11", b = "1" 输出:"100"示例 2:
输入:a = "1010", b = "1011" 输出:"10101"
char* addBinary(char* a, char* b) {
int lenA = strlen(a);
int lenB = strlen(b);
int maxLen = lenA > lenB ? lenA : lenB;
//为结果多加一位,以防最后有进位
char* result = (char*)malloc(maxLen + 2); //一个给进位另一个给 '\0';
int carry = 0;
int index = 0;
//从后向前进行二进制加法:
while(lenA > 0 || lenB > 0 || carry){
int bitA = lenA > 0 ? a[lenA - 1] - '0' : 0;
int bitB = lenB > 0 ? b[lenB - 1] - '0' : 0;
int sum = bitA + bitB + carry;
result[index++] = (sum % 2) + '0'; // 存储当前位
carry = sum / 2; // 更新进位
lenA--;
lenB--;
}
// 结果数组反转,因为从低位开始加
result[index] = '\0'; // 添加字符串结束符
// 修正反转逻辑
for (int i = 0, j = index - 1; i < j; i++, j--) {
char temp = result[i];
result[i] = result[j];
result[j] = temp;
}
return result;
}
x的平方:
奇怪,二分法用
mid = (left + right) / 2;就不行
int mid = left + (right - left) / 2; 就是可以的
通过改成
mid = left + (right - left) / 2;
,我们首先计算right - left
,这通常不会超出int
的范围,因为right - left
的差值一般比left + right
的和要小得多。然后,除以 2 后,计算出的结果不会超出int
的范围,最后再加上left
,得出的mid
也不会溢出。例如:
- 假设
left = 2,000,000,000
和right = 2,000,000,000
,计算right - left = 0
,然后0 / 2 = 0
,最后mid = 2,000,000,000 + 0 = 2,000,000,000
,完全在范围内。这种方法保证了加法操作总是先进行小的差值计算,避免了大数相加导致溢出的风险。
int mySqrt(int x) {
if (x == 0) return 0;
int left = 1,right = x;
while (left <= right)
{
int mid = left + (right - left) / 2;
long long square = (long long) mid * mid;
if (square == x){
return mid;
}
else if (square > x)
{
right = mid - 1;
}
else{
left = mid + 1;
}
}
return right;
}
二叉树前序遍历:
#include <bits/stdc++.h>
struct treeNode{
int val;
struct treeNode *left;
struct treeNode *right;
};
void preOrder(struct treeNode* root,int* res,int* resSize) {
if(root = NULL) return ;
res[(*resSize)++] = root->val;
preOrder(root->left,res,resSize);
preOrder(root->right,res,resSize);
}
int ii(struct treeNode* root,int* returnSize){
int* res = (int*)malloc(sizeof(int) * 101);
int *returnSize = 0;
preOrder(root,res,returnSize);
return res;
}
删除排序链表中的重复元素:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head) {
if(head == NULL){
return head;
}
struct ListNode* current = head;
//遍历列表
while(current != NULL && current->next != NULL){
//如果当前节点的值和下一次节点的值相同
if(current->val == current->next->val){
//跳过,下一个节点
struct ListNode* temp = current->next;
current->next = temp->next;
free(temp);
}else{
current = current->next;
}
}
return head;
}