个人学习编程(3-29) leetcode刷题

最后一个单词的长度:

思路:跳过末尾的空格,可以从后向前遍历

然后再利用 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]。
cpp 复制代码
/**
 * 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"
cpp 复制代码
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,000right = 2,000,000,000,计算 right - left = 0,然后 0 / 2 = 0,最后 mid = 2,000,000,000 + 0 = 2,000,000,000,完全在范围内。

这种方法保证了加法操作总是先进行小的差值计算,避免了大数相加导致溢出的风险。

cpp 复制代码
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;
    
}

二叉树前序遍历:

cpp 复制代码
#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;
}

删除排序链表中的重复元素:

cpp 复制代码
/**
 * 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;
}
相关推荐
@小匠1 小时前
Read Frog:一款开源的 AI 驱动浏览器语言学习扩展
人工智能·学习
W23035765734 小时前
经典算法:最长上升子序列(LIS)深度解析 C++ 实现
开发语言·c++·算法
minji...5 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
语戚6 小时前
力扣 968. 监控二叉树 —— 贪心 & 树形 DP 双解法递归 + 非递归全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·
skywalker_116 小时前
力扣hot100-7(接雨水),8(无重复字符的最长子串)
算法·leetcode·职场和发展
bIo7lyA8v7 小时前
算法稳定性分析中的输入扰动建模的技术9
算法
CoderCodingNo7 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
sinat_286945197 小时前
AI Coding 时代的 TDD:从理念到工程落地
人工智能·深度学习·算法·tdd
炽烈小老头7 小时前
【 每天学习一点算法 2026/04/12】x 的平方根
学习·算法