当前位置:   article > 正文

Leetcode 54.螺旋矩阵和Leetcoed 707.设计链表

Leetcode 54.螺旋矩阵和Leetcoed 707.设计链表


Leetcode 54.螺旋矩阵

题目描述

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2 :

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

C语言题解和思路

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize) {
    int row = matrixColSize[0], col = matrixSize;
    int total = row * col;
    int *str = (int *)malloc(sizeof(int) * total);
    *returnSize = 0;
    if(row == 0 || col == 0)
    {
        return NULL;
    }
    int left = 0, right = matrixColSize[0] - 1, top = 0, bottom = matrixSize - 1, i;
    while(left <= right && top <= bottom)
    {
        for(i = left; i <= right; i++)
        {
            str[(*returnSize)++] = matrix[top][i];
        }
        top++;
        for(i = top; i <= bottom; i++)
        {
            str[(*returnSize)++] = matrix[i][right];
        }
        right--;
        if(left <= right && top <= bottom)
        {
            for(i = right; i >= left; i--)
            {
                str[(*returnSize)++] = matrix[bottom][i];
            }
            bottom--;
            for(i = bottom; i >= top; i--)
            {
                str[(*returnSize)++] = matrix[i][left];
            }
            left++;
        } 
    }
    return str;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

解题思路:

顺时针遍历数组的顺序为:

  • 在上行从左到右遍历;
  • 在右行从上到下遍历;
  • 在下行从右到左遍历;
  • 在左行从下到上遍历;

循环前先判断数组是否为空,如果数组为空,直接返回 NULL ,节省时间。

进入循环,当 left 大于 right 或 top 大于 bottom 时,终止循环。在循环里,按上右下左的顺序分别遍历二维数组,将值赋给我们要返回的数组。

注意:在循环完上边和右边后,我们必须重新判断一次循环条件,才能决定是否继续遍历下行和左行,因为题目给的行和列的数量不一定相等,所以可能会出现同一个值被重复赋予数组,使数组越界。

Leetcoed 707.设计链表

题目描述

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

  • MyLinkedList() 初始化 MyLinkedList 对象。
  • int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
  • void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
  • void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
  • void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
  • void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

示例:

输入:
[“MyLinkedList”, “addAtHead”, “addAtTail”, “addAtIndex”, “get”, “deleteAtIndex”, “get”]
[[], [1], [3], [1, 2], [1], [1], [1]]
输出:
[null, null, null, null, 2, null, 3]

解释:

MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3
myLinkedList.get(1);              // 返回 2
myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3
myLinkedList.get(1);              // 返回 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

提示:

  • 0 <= index, val <= 1000
  • 请不要使用内置的 LinkedList 库。
  • 调用 get、addAtHead、addAtTail、addAtIndex 和 deleteAtIndex 的次数不超过 2000 。

C语言解题和思路

typedef struct MyLinkedList{
    int val;
    struct MyLinkedList *next;
} MyLinkedList;


MyLinkedList* myLinkedListCreate() {
    MyLinkedList *head = (MyLinkedList *)malloc(sizeof(MyLinkedList));
    head->next = NULL;
    return head;
}

int myLinkedListGet(MyLinkedList* obj, int index) {
    MyLinkedList* move = obj->next;
    for(int i = 0; move != NULL; i++)
    {
        if(i == index)
        {
            return move->val;
        }
        move = move->next;
    }
    return -1;
}

void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
    MyLinkedList *p = (MyLinkedList *)malloc(sizeof(MyLinkedList));
    p->next = NULL;
    p->val = val;
    p->next = obj->next;
    obj->next = p;
}

void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
    MyLinkedList* move = obj;
    MyLinkedList* p = (MyLinkedList *)malloc(sizeof(MyLinkedList));
    p->next = NULL;
    p->val = val;
    while(move->next)
    {
        move = move->next;
    }
    move->next = p;
}

void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
    if(index == 0)
    {
        myLinkedListAddAtHead(obj, val);
        return;
    }
    MyLinkedList *move = obj->next;
    for(int i = 1; move != NULL; i++)
    {
        if(index == i)
        {
            MyLinkedList *p = (MyLinkedList *)malloc(sizeof(MyLinkedList));
            p->next = NULL;
            p->val = val;
            p->next = move->next;
            move->next = p;
        }
        move = move->next;
    }
}

void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
    if(0 == index)
    {
        if(obj->next != NULL)
        {
            obj->next = obj->next->next;
        }
    }
    MyLinkedList *move = obj->next;
    for(int i = 1; move != NULL; i++)
    {
        if(i == index)
        {
            if(move->next != NULL)
            {
                move->next = move->next->next;
            }
            return;
        }
        move = move->next;
    }
}

void myLinkedListFree(MyLinkedList* obj) {
    while(obj != NULL)
    {
        MyLinkedList *p = obj;
        obj = obj->next;
        free(p);
    }
}

/**
 * Your MyLinkedList struct will be instantiated and called as such:
 * MyLinkedList* obj = myLinkedListCreate();
 * int param_1 = myLinkedListGet(obj, index);
 
 * myLinkedListAddAtHead(obj, val);
 
 * myLinkedListAddAtTail(obj, val);
 
 * myLinkedListAddAtIndex(obj, index, val);
 
 * myLinkedListDeleteAtIndex(obj, index);
 
 * myLinkedListFree(obj);
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

解题思路:

此解法使用单链表,题中操作包括链表结点结构的定义、链表节点的建立和初始化、链表的头插法、链表的尾插法、链表的插入、链表结点删除、链表查询、链表的释放。

结构体构建时,如果要引用结构体自身,需要为结构体命名。

MyLinkedList* myLinkedListCreate() 函数用来建立一个链表结点并将其初始化,最后返回该节点。

int myLinkedListGet(MyLinkedList* obj, int index) 函数查找下标为 index 的链表节点的值。因为这里是设置虚拟头结点进行操作,所以设置一个链表指针 move 指向传入的头指针 obj 的下一个结点,for循环寻找到对应下标后返回该节点的值,如果在循环中未找到该节点,结束循环后返回 -1 。

void myLinkedListAddAtHead(obj, val) 函数将结点插入链表的头部。建立一个指针 p 并初始化,将 val 值赋给结点,让指针 p 的下一位指向头指针的下一位,再让头指针的下一位指向 p 。

void myLinkedListAddAtTail(MyLinkedList* obj, int val) 函数将结点连接到链表的尾部。通过指针 move 找到最后一个结点,然后把新的结点连上。

void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) 函数在对应下标位置插入结点。如果下标为 0 ,直接调用头插法函数。如果不为 0 ,则从 1 开始循环,如果下标不大于链表长度,会在对应位置插入结点。

void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) 函数删除对应下标位置的结点,,下标为 0 要单独处理,因为头节点是虚拟头节点,不算在链表里,结点为空,循环时从 1 开始,因为删除结点要将该下标的上一个结点连向该下标的下一个结点。

void myLinkedListFree(MyLinkedList* obj) 函数释放链表空间,将链表从头节点开始,一节一节往后释放结点空间。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/389237
推荐阅读
相关标签
  

闽ICP备14008679号