赞
踩
给你一个 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]
/** * 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; }
解题思路:
顺时针遍历数组的顺序为:
- 在上行从左到右遍历;
- 在右行从上到下遍历;
- 在下行从右到左遍历;
- 在左行从下到上遍历;
循环前先判断数组是否为空,如果数组为空,直接返回 NULL ,节省时间。
进入循环,当 left 大于 right 或 top 大于 bottom 时,终止循环。在循环里,按上右下左的顺序分别遍历二维数组,将值赋给我们要返回的数组。
注意:在循环完上边和右边后,我们必须重新判断一次循环条件,才能决定是否继续遍历下行和左行,因为题目给的行和列的数量不一定相等,所以可能会出现同一个值被重复赋予数组,使数组越界。
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
实现 MyLinkedList 类:
示例:
输入:
[“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
提示:
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); */
解题思路:
此解法使用单链表,题中操作包括链表结点结构的定义、链表节点的建立和初始化、链表的头插法、链表的尾插法、链表的插入、链表结点删除、链表查询、链表的释放。
结构体构建时,如果要引用结构体自身,需要为结构体命名。
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) 函数释放链表空间,将链表从头节点开始,一节一节往后释放结点空间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。