正则表达式匹配
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
public class Solution {
public boolean match(char[] str, char[] pattern){
if (str == null || pattern == null)
return false;
return matchCore(str, 0, pattern, 0);
}
private boolean matchCore(char[] str, int s, char[] pattern, int p) {
//下面4行是递归结束标志,两个指针都指到了最后,才是匹配,否则不匹配
if (s == str.length && p == pattern.length)
return true;
if (s < str.length && p == pattern.length)
return false;
//虽然比的是P位置的,但是P后面出现*时,规则需要改变。
if (p + 1 < pattern.length && pattern[p + 1] == '*') {
//出现了*,并且s和P指向的相同,3种情况并列
if ((s < str.length && pattern[p] == '.')
|| (s < str.length && pattern[p] == str[s])) {
return matchCore(str, s, pattern, p + 2)
|| matchCore(str, s + 1, pattern, p)
|| matchCore(str, s + 1, pattern, p + 2);
} else {//出现了*,并且s和p指向的不同,那就把*前面的字符理解出现了0次,p+2
return matchCore(str, s, pattern, p + 2);
}
}
//说明P后面不是*,那么就进行常规判断。相同就分别给指针+1
if (s < str.length && (pattern[p] == str[s] || pattern[p] == '.'))
return matchCore(str, s + 1, pattern, p + 1);
//p后面又不是*,也没有.给你撑腰,你还敢出现不同,那必然false
return false;
}
}
class Solution {
public:
bool match(char* s, char* p)
{ // 如果 s 和 p 同时为空
if (*s == '\0' && *p == '\0') return true;
// 如果 s不为空, 但是 p 为空
if (*p == '\0') return false;
// 如果没有 '*'
if (*(p+1) != '*') {
if (*s != '\0' && (*s == *p || *p == '.'))
return match(s+1, p+1);
else
return false;
}
// 如果有 '*'
else {
bool ret = false;
// 重复 1 次或多次
if (*s != '\0' && (*s == *p || *p == '.'))
ret = match(s+1, p);
// 重复 0 次
return ret || match(s, p+2);
}
}
};
表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
public class Solution {
public boolean isNumeric(char[] str) {
// 标记符号、小数点、e是否出现过
boolean sign = false,decimal = false,hasE = false;
for(int i = 0; i < str.length; i++){
if(str[i] == 'e' || str[i] == 'E'){
if(i == str.length - 1) return false;// e后面一定要接数字
if(hasE == true) return false;// 不能同时存在两个e
hasE = true;
}else if(str[i] == '+' || str[i] == '-'){
// 第二次出现+-符号,则必须紧接在e之后
if(sign == true && str[i-1] != 'e' && str[i-1] != 'E') return false;
// 第一次出现+-符号,且不是在字符串开头,则也必须紧接在e之后
if(sign == false && i > 0 && str[i-1] != 'e' && str[i-1] != 'E') return false;
sign =true;
}else if(str[i] == '.'){
// e后面不能接小数点,小数点不能出现两次
if(hasE == true || decimal == true) return false;
decimal = true;
}else if(str[i] < '0' || str[i] > '9')// 不合法字符
return false;
}
return true;
}
}
class Solution {
public:
bool isNumeric(char* str) {
// 标记符号、小数点、e是否出现过
bool sign = false, decimal = false, hasE = false;
for (int i = 0; i < strlen(str); i++) {
if (str[i] == 'e' || str[i] == 'E') {
if (i == strlen(str)-1) return false; // e后面一定要接数字
if (hasE) return false; // 不能同时存在两个e
hasE = true;
} else if (str[i] == '+' || str[i] == '-') {
// 第二次出现+-符号,则必须紧接在e之后
if (sign && str[i-1] != 'e' && str[i-1] != 'E') return false;
// 第一次出现+-符号,且不是在字符串开头,则也必须紧接在e之后
if (!sign && i > 0 && str[i-1] != 'e' && str[i-1] != 'E') return false;
sign = true;
} else if (str[i] == '.') {
// e后面不能接小数点,小数点不能出现两次
if (hasE || decimal) return false;
decimal = true;
} else if (str[i] < '0' || str[i] > '9') // 不合法字符
return false;
}
return true;
}
};
字符流中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
public class Solution {
//Insert one char from stringstream
public int[] hash = new int[128];
StringBuffer s = new StringBuffer();
public void Insert(char ch)
{
s.append(ch);
hash[ch]++;
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if(hash[c] == 1)
return c;
}
return '#';
}
}
class Solution
{
public:
//Insert one char from stringstream
string s;
char hash[256]={0};
void Insert(char ch)
{
s+=ch;
hash[ch]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
int size=s.size();
for(int i=0;i<size;++i)
{
if(hash[s[i]]==1)
return s[i];
}
return '#';
}
};
链表中环的入口节点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
ListNode slow = pHead,fast = pHead;
boolean found = false;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
found = true;
break;
}
}
if(!found) return null;
slow = pHead;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode*fast=pHead,*low=pHead;
while(fast&&fast->next){
fast=fast->next->next;
low=low->next;
if(fast==low)
break;
}
if(!fast||!fast->next)return NULL;
low=pHead;//low从链表头出发
while(fast!=low){//fast从相遇点出发
fast=fast->next;
low=low->next;
}
return low;
}
};
删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) { // 只有0个或1个结点,则返回
return pHead;
}
if (pHead.val == pHead.next.val) { // 当前结点是重复结点
ListNode pNode = pHead.next;
while (pNode != null && pNode.val == pHead.val) {
// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
pNode = pNode.next;
}
return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归
} else { // 当前结点不是重复结点
pHead.next = deleteDuplication(pHead.next); // 保留当前结点,从下一个结点开始递归
return pHead;
}
}
}
// public class Solution {
// public ListNode deleteDuplication(ListNode pHead)
// {
// if(pHead == null || pHead.next==null){return pHead;}
// ListNode head = new ListNode(0);
// head.next = pHead;
// ListNode pre = head;
// ListNode last = head.next;
// while(last!= null){
// if(last.next!=null && last.val==last.next.val){
// while(last.next!=null && last.val==last.next.val){
// last = last.next;
// }
// pre.next = last.next;
// last = last.next;
// }else{
// pre = pre.next;
// last = last.next;
// }
// }
// return head.next;
// }
// }
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
ListNode *vhead = new ListNode(-1);
vhead->next = pHead;
ListNode *pre = vhead, *cur = pHead;
while (cur) {
if (cur->next && cur->val == cur->next->val) {
cur = cur->next;
while (cur->next && cur->val == cur->next->val) {
cur = cur->next;
}
cur = cur->next;
pre->next = cur;
}
else {
pre = cur;
cur = cur->next;
}
}
return vhead->next;
}
};
/*
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) { // 只有0个或1个结点,则返回
return pHead;
}
if (pHead.val == pHead.next.val) { // 当前结点是重复结点
ListNode pNode = pHead.next;
while (pNode != null && pNode.val == pHead.val) {
// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
pNode = pNode.next;
}
return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归
} else { // 当前结点不是重复结点
pHead.next = deleteDuplication(pHead.next); // 保留当前结点,从下一个结点开始递归
return pHead;
}
}
}
*/