有效的括号
题目要求
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
用例输入
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
做题思路
这道题的要求是需要我们判断给的括号是否合法,意思就是当我们遇到有括号的时候,我们需要判断左边最近的左括号是否跟这个右括号匹配。我们可以使用一种数据结构:栈来解决这个问题,因为栈是一端进,一端出,这一端被称为栈顶,先进后出,后进先出。所以我们把左括号都放在栈中,当遇到右括号时,我们就从栈顶取出左括号,看是否跟这个右括号匹配,匹配就继续下一个字符,不匹配就返回true。当这个字符串遍历完后,如果栈中不为空,说明有左括号未匹配,返回false,否则返回true。
代码实现
bool isValid(char * s){ int len = strlen(s); //当字符串中没有或者只有一个字符时就直接返回false if(len <= 1) return false; //字符个数为奇数就说明一定有一个未匹配所以就直接返回 if(len%2 == 1) return false; //tail记录栈顶的位置 int tail = 0; char* arr = (char*)malloc(len*sizeof(char)); int i = 0; for(int i = 0; i<len; i++) { if(s[i] == '(' || s[i] == '[' || s[i] == '{') { arr[tail++] = s[i]; } else { if(tail == 0) return false; if(s[i] == ')') { if(arr[tail-1] != '(') return false; } else if(s[i] == ']') { if(arr[tail-1] != '[') { return false; } } else { if(arr[tail-1] != '{') { return false; } } tail--; } } if(tail == 0) return true; return false; }
环形链表
题目要求
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
用例输入
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
做题思路
如果该链表是有环的,那么我们使用两个指针:快指针跟慢指针,慢指针一次走一个结点,快指针走两个结点,他们最终一定会相遇。
代码实现
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ bool hasCycle(struct ListNode *head) { struct ListNode* low = head; struct ListNode* fast = head; while(fast && fast->next) { low = low->next; fast = fast->next->next; if(low == fast) return true; } return false; }
环形链表 II
题目要求
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
用例输入
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
做题思路
我们这个题还得需要上面的判断是否是环形链表的知识,有一个结论:当快慢指针相遇的时候,让指针分别在链表的头结点跟相遇的结点开始走,每次走一个结点,他们最终会在环形链表的入口处相遇。
代码实现
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode *detectCycle(struct ListNode *head) { struct ListNode* slow = head; struct ListNode* fast = head; while(fast && fast->next) { slow = slow->next; fast = fast->next->next; if(slow == fast) { struct ListNode* meet = slow; while(head != meet) { meet = meet->next; head = head->next; } return meet; } } return NULL; }