leetcode 第一周 c

本文探讨了一系列算法挑战,包括判断机器人是否能返回原点、计算数字的补码、反转字符串、计算岛屿周长、搜索二叉搜索树中的节点、计算二叉树的层级平均值以及检测数组中是否存在重复元素。每个问题都提供了详细的解决思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

657. Robot Return to Origin
description:
There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its moves, judge if this robot ends up at (0, 0) after it completes its moves.
The move sequence is represented by a string, and the character moves[i] represents its ith move. Valid moves are R (right), L (left), U (up), and D (down). If the robot returns to the origin after it finishes all of its moves, return true. Otherwise, return false.
Note: The way that the robot is "facing" is irrelevant. "R" will always make the robot move to the right once, "L" will always make it move left, etc. Also, assume that the magnitude of the robot's movement is the same for each move.
思路:在二维方向上各维持一个数字,然后判断两个数字是否都为0。
 

bool judgeCircle(char* moves) {
    if(NULL == moves || strlen(moves) == 0){
        return true;
    }
    
    int i;
    int is_up = 0;
    int is_left = 0;
    int len = strlen(moves);
    
    for(i = 0; i < len; i++){
        if(moves[i] == 'U'){
            is_up += 1;
        }else if(moves[i] == 'D'){
            is_up -= 1;
        }else if(moves[i] == 'L'){
            is_left += 1;
        }else{
            is_left -= 1;
        }
    }
    return !(is_up || is_left);
}

476. Number Complement
description:
Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.
Note:
1.    The given integer is guaranteed to fit within the range of a 32-bit signed integer.
2.    You could assume no leading zero bit in the integer’s binary representation.
思路:通过位移或者整除对所在位求反,然后累加对应位代表的数输出总数。
 

int findComplement(int num) {
    int j = 0;
    int k = 0;
    
    if(!num){
        return 1;
    }
    
    while(num){
        k += (1 << j) * !(num % 2);
        j++;
        num /= 2;
    }
    return k;
}

344. Reverse String
description:
Write a function that takes a string as input and returns the string reversed.
思路:计算长度,然后首尾交换。
 

char* reverseString(char* s) {
    if(NULL == s){
        return s;
    }
    
    int len = strlen(s);
    int c_temp;
    int i;
    for(i = 0; i < len/2; i++){
        c_temp = s[i];
        s[i] = s[len - i -1];
        s[len - i -1] = c_temp;
    }
    return s;
}

463. Island Perimeter
description:
You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.
思路:二维方向上分别遍历网格,计算出覆盖的数目以及相连的数目,根据公式计算:覆盖数目*4 – 相连数目 * 2。
 

int islandPerimeter(int** grid, int gridRowSize, int gridColSize) {
    if(NULL == grid || 0 == gridRowSize || 0 == gridColSize){
        return 0;
    }
    int i, j, pre, num = 0, connect = 0;
    for(i = 0; i < gridRowSize; i++){
        pre = 0;
        for(j = 0; j < gridColSize; j++){
            if(grid[i][j]){
                num++;
            }
            if(pre && grid[i][j]){
                connect++;
            }
            pre = grid[i][j];
        }
    }

    for(i = 0; i < gridColSize; i++){
        pre = 0;
        for(j = 0; j < gridRowSize; j++){
            if(pre && grid[j][i]){
                connect++;
            }
            pre = grid[j][i];
        }
    }

    return num * 4 - connect * 2;
}

700. Search in a Binary Search Tree
description:
Given the root node of a binary search tree (BST) and a value. You need to find the node in the BST that the node's value equals the given value. Return the subtree rooted with that node. If such node doesn't exist, you should return NULL.
思路:利用bst的规则进行寻找。
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* searchBST(struct TreeNode* root, int val) {
    if(NULL == root){
        return root;
    }
	
	if(val==(root->val))
		return root;
	if(val<(root->val))
		return searchBST(root->left,val);
	if(val>(root->val))
		return searchBST(root->right,val);
	
	return NULL;
}

637. Average of Levels in Binary Tree
description:
Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array.
我的思路:先序遍历该树,然后分别计算各层的和,以及所在层的数目,这里是动态申请内存,然后修改其值,值得注意的是,由于栈会保存当前的情况,所以需要利用其地址去修改对应的值。另一点要注意的是要确认是否会出现数据溢出,比如此次的相加。
其他思路:先计算深度,然后申请内存,逐层计算。
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
/*
#define FREE_MEM if(sum){\
                    free(sum);\
                 }\
                 if(num){\
                    free(num);\
                 }

#define ERROR_HANDLE *returnSize = 0;\
        return NULL;

int statistics_levels(struct TreeNode *root, int *depth, int cur, long long **sum, int **num)
{
    if(NULL == root){
        return 0;
    }
	
	long long *p_sum = NULL;
	int *p_num = NULL;
	
    if(cur > *depth){
        *depth = cur;
		p_sum = malloc(*depth * sizeof(long long));
		if(NULL == p_sum){
			return -1;
		}
		memset(p_sum, 0, *depth * sizeof(long long));
		if(*sum){
			memcpy(p_sum, *sum, (*depth-1) * sizeof(long long));
			free(*sum);
		}
		*sum = p_sum;
		
		p_num = malloc(*depth * sizeof(int));
		if(NULL == p_num){
			return -1;
		}
		memset(p_num, 0, *depth * sizeof(int));
		if(*num){
			memcpy(p_num, *num, (*depth-1) * sizeof(int));
			free(*num);
		}
		
		*num = p_num;
    }
    
   
    (*sum)[cur-1] += root->val;
    (*num)[cur-1]++;
    
    statistics_levels(root->left, depth, cur+1, sum, num);
    statistics_levels(root->right, depth, cur+1, sum, num);
    return 0;
}

double* averageOfLevels(struct TreeNode* root, int* returnSize) {
    if(NULL == root){
        ERROR_HANDLE
    }
    
    long long *sum = NULL;
    int *num = NULL;
    double *average = NULL;
    *returnSize = 0;
    int cur = 0;
    int i;
    
    if(!statistics_levels(root, returnSize, cur+1, &sum, &num)){
        average = malloc(sizeof(double) * (*returnSize));
        if(NULL == average){
            FREE_MEM
            ERROR_HANDLE
        }

        for(i = 0; i < *returnSize; i++){
            average[i] = (double)sum[i] / (double)num[i];
        }
        FREE_MEM
    }else{
        FREE_MEM
        ERROR_HANDLE
    }
    return average;
}

*/








/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */

#define max(a,b)    (((a) > (b)) ? (a) : (b))

typedef struct _list {
        struct TreeNode *node;
        struct _queue *next;
} list;

typedef struct _queue {
        list *head;
        list *tail;
} queue;

queue *create_queue()
{
        queue *myq = (queue *)calloc(1, sizeof(queue));
        return (myq);
}

void enqueue(queue *myq, struct TreeNode *node) {
        list *elem = (list *)calloc(1, sizeof(elem));
        elem->node = node;
        if (myq->head == NULL) {
                myq->head = elem;
                myq->tail = elem;
                return;
        }

        myq->tail->next = elem;
        myq->tail = elem;
}

struct TreeNode* dequeue(queue* myq)
{
        list *elem = myq->head;
        assert (elem != NULL);

        struct TreeNode *node = elem->node;
        if (myq->tail == myq->head)
                myq->tail = NULL;

        myq->head = myq->head->next;
        return (node);
}

int is_empty(queue *myq) {
        if (myq->head == NULL)
                return (1);
        else
                return (0);
}

void destroy_queue(queue *myq)
{
        list *elem = myq->head;
        list *temp;
        while (elem != NULL) {
                temp = elem;
                elem = elem->next;
                free(temp);
        }
}

int treeDepth(struct TreeNode *root)
{
    int ldepth, rdepth;
    if (root == NULL)
        return (0);
    
    ldepth = treeDepth(root->left);
    rdepth = treeDepth(root->right);
    return (max(ldepth, rdepth) + 1);
}

double* averageOfLevels(struct TreeNode* root, int* returnSize) {
    *returnSize = 0;
    if (root == NULL)
        return (NULL);
    int depth = treeDepth(root);
    int num, k = 0;
    double total;
    struct TreeNode *node;
    double *avg = (double *)calloc(depth, sizeof(double));
    queue *q1, *q2, *qtemp;
    q1 = create_queue();
    q2 = create_queue();
    enqueue(q1, root);
    
    while (1) {
        total = 0;
        num = 0;
        while (!is_empty(q1)) {
            node = dequeue(q1);
            total += node->val;
            num++;
            if (node->left != NULL)
                enqueue(q2, node->left);
            if (node->right != NULL)
                enqueue(q2, node->right);
        }
        avg[k++] = total/num;
        
        if (is_empty(q2))
            break;
        
        qtemp = q2;
        q2 = q1;
        q1 = qtemp;
    }
    *returnSize = depth;
    return (avg);
}

217. Contains Duplicate
description:
Given an array of integers, find if the array contains any duplicates.
Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
思路:快速排序,然后前后对比。自己写了个,后边用glibc自带了,比较好吃。
 

int cmpfunc (const void * a, const void * b) {
   return ( *(int*)a - *(int*)b );
}

bool containsDuplicate(int* nums, int numsSize) {
    
    qsort(nums, numsSize, sizeof(int), cmpfunc);
    int i;
   
    for (i = 0; i < numsSize-1; i++){
        if(nums[i] == nums[i+1]){
            return true;
        }
    }
    
    return false;
    
    
}

 

<think>好的,用户现在问的是“如何一周学会”,结合之前的对话历史,用户之前询问了谭浩强的《C语言程序设计(第五版)》,所以这里的“一周学会”应该是指一周内学会C语言。 首先,用户可能是个编程新手,急于快速掌握C语言,可能是为了应对考试、项目或者面试。需要明确一周的时间确实非常紧张,但用户可能希望得到高效的学习策略,尽可能在短时间内掌握基础。 接下来,我需要评估用户的真实需求。用户可能知道一周时间不足以精通,但想要快速入门,了解核心概念,能完成简单编程任务。因此,我的回答需要设定合理的预期,同时提供可行的计划。 然后,考虑如何结构化回答。应该分步骤,明确每天的学习重点,强调实践和核心知识点。同时需要提醒用户时间有限,重点抓基础,比如变量、控制结构、函数、数组和指针,这些是C语言的关键部分。 还要注意用户之前提到的书籍,谭浩强的教材可能作为参考,但一周内可能无法详细阅读全书,所以需要提炼重点章节,比如数据类型、运算符、控制结构、函数、数组和指针。建议用户结合教材的示例和习题进行练习。 另外,用户可能没有足够的时间做复杂的项目,但可以推荐小练习,如计算器、成绩管理系统,这些能在短时间内完成,巩固所学知识。 需要注意潜在的问题,比如用户可能低估C语言的难度,特别是指针和内存管理部分。需要提醒这些是难点,但在一周内至少理解基本概念,后续再深入。 最后,总结时强调持续学习的重要性,一周只是入门,后续还需不断练习和扩展知识。同时提供资源推荐,帮助用户找到合适的学习材料。</think>--- **一周学会C语言编程的快速学习指南** (注:C语言需要长期实践才能真正掌握,但一周内可掌握基础语法并完成简单程序) --- ### **1. 明确目标与时间分配** - **目标**:掌握基础语法,能编写简单程序(如计算器、成绩管理系统)。 - **时间规划**: - **Day 1-2**:基础语法(变量、运算符、输入输出) **示例**:用`printf`输出`Hello World`,用`scanf`输入数值并计算$1+2$。 - **Day 3-4**:控制结构(分支`if-else`、循环`for/while`) **示例**:编写九九乘法表,判断素数。 - **Day 5**:函数与数组 **示例**:用函数实现冒泡排序,用数组存储学生成绩。 - **Day 6**:指针基础 **示例**:通过指针交换两个变量的值。 - **Day 7**:综合实践 **示例**:结合文件操作(`fopen`)实现简易通讯录。 --- ### **2. 核心学习内容** #### **基础语法(必学)** - **变量与数据类型**:`int`, `float`, `char`等。 - **运算符**:算术($+$、$-$)、关系($>$、$==$)、逻辑(`&&`、`||`)。 - **输入输出**:`printf`、`scanf`函数。 - **代码片段**: ```c int a, b; scanf("%d %d", &a, &b); printf("Sum: %d", a + b); ``` #### **控制结构(重点)** - **分支语句**:`if-else`、`switch-case`。 - **循环语句**:`for`、`while`、`do-while`。 - **代码片段**(判断闰年): ```c if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) printf("Leap year"); else printf("Not leap year"); ``` #### **函数与数组(实践关键)** - **函数定义**:参数传递(值传递 vs. 指针传递)。 - **数组操作**:一维/二维数组遍历。 - **代码片段**(求数组最大值): ```c int max(int arr[], int n) { int m = arr[0]; for (int i = 1; i < n; i++) if (arr[i] > m) m = arr[i]; return m; } ``` #### **指针(难点)** - **基本概念**:指针变量`int *p`,取地址符`&`。 - **代码片段**(交换变量): ```c void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } ``` --- ### **3. 高效学习方法** 1. **直接写代码**:每学一个语法立即写代码测试(例如学完`for`循环马上写九九乘法表)。 2. **调试优先**:遇到错误时,用`printf`输出中间变量值排查问题。 3. **简化逻辑**:复杂问题拆解为小函数(如将“成绩统计”拆分为输入、计算、输出函数)。 --- ### **4. 推荐实践项目** - **Day 3**:计算器(支持加减乘除) - **Day 5**:学生成绩管理系统(数组存储数据,函数计算平均分) - **Day 7**:文件版通讯录(用`fprintf`保存数据) --- ### **5. 注意事项** - **避免深陷细节**:如暂不深究`volatile`、`位域`等高级特性。 - **时间管理**:每天至少3小时专注学习(2小时学语法,1小时写代码)。 - **资源推荐**: - **工具**:OnlineGDB(在线编译器,无需安装) - **文档**:菜鸟教程C语言专题(快速查阅语法) --- ### **总结** 一周学习需聚焦**基础语法+核心逻辑**,通过大量代码练习快速上手。完成学习后,可进一步学习《C Primer Plus》或尝试LeetCode简单题巩固能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值