leetcode:https://leetcode-cn.com/problemset/algorithms/ 类别:热题HOT100 easy篇 共26道
No.21 -------------- 可将滑动窗口作为一个章节来看啦。。。
标签:哈希表,滑动窗口
438. Find All Anagrams in a String
找异位词的字串起始索引
异位词:字母相同,但排列不同的字符串
思想:滑动窗口通用思想解决字串问题,双指针技巧(窗口的左右界限)
这道题要找长度相同的子串,也就是「字母异位词」嘛。
class Solution {
public:
vector<int> findAnagrams(string s, string t) {
// 用数组记录答案
vector<int> res;
int left = 0, right = 0;
unordered_map<char, int> needs;
unordered_map<char, int> window;
for (char c : t) needs[c]++;
int match = 0;
while (right < s.size()) {
char c1 = s[right];
if (needs.count(c1)) {
window[c1]++;
if (window[c1] == needs[c1])
match++;
}
right++;
while (match == needs.size()) {
// 如果 window 的大小合适
// 就把起始索引 left 加入结果
if (right - left == t.size()) {
res.push_back(left);
}
char c2 = s[left];
if (needs.count(c2)) {
window[c2]--;
if (window[c2] < needs[c2])
match--;
}
left++;
}
}
return res;
}
};
滑动窗口总结
No.22
考点:链表
160. Intersection of Two Linked Lists
相交链表
给定两个链表,请找它们的交汇点。
注意:
如果两个链表不相交,则返回 null;
在函数结束时,两个链表必须保持原来的结构;
链表中不存在环;
你的代码需要的时间复杂度是 O(n)O(n),额外的空间复杂度是 O(1)O(1);
思路:双指针扫描
创建两个指针 pA 和 pB,分别初始化为链表 A 和 B 的头结点。然后让它们向后逐结点遍历。
当 pA 到达链表的尾部时,将它重定位到链表 B 的头结点 (你没看错,就是链表 B); 类似的,当 pB 到达链表的尾部时,将它重定位到链表 A 的头结点。
若在某一时刻 pA 和 pB相遇,则 pA/pB为相交结点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p = headA, *q = headB;
while (p != q)
{
if (p) p = p->next;
else p = headB;
if (q) q = q->next;
else q = headA;
}
return p;
}
};
方法2:先构成环,再用快慢指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode* last = headB;
while (last->next != nullptr) {
last = last->next;
}
last->next = headB;
ListNode* fast = headA;
ListNode* slow = headA;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
slow = headA;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
last->next = nullptr;
return fast;
}
}
last->next = nullptr;
return nullptr;
}
};
No.23
考点:链表
141. Linked List Cycle
环形链表
Given a linked list, determine if it has a cycle in it.
思路:使用快慢指针,若指针相遇则判断有环。
慢指针每次移动一步,而快指针每次移动两步。如果列表中不存在环,最终快指针将会最先到达尾部,此时我们可以返回 false。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if (head == nullptr || head->next == nullptr) {
return false;
}
ListNode* slow = head;
ListNode* fast = head->next;
while (slow != fast) {
if (fast == nullptr || fast->next == nullptr) {
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};
No.24
考点:链表
21. Merge Two Sorted Lists
合并两个有序链表
思路:建立头节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy = new ListNode(0);
ListNode *cur = dummy;
while (l1 != NULL && l2 != NULL) {
if (l1 -> val < l2 -> val) {
cur -> next = l1;
l1 = l1 -> next;
}
else {
cur -> next = l2;
l2 = l2 -> next;
}
cur = cur -> next;
}
cur -> next = (l1 != NULL ? l1 : l2);
return dummy -> next;
}
};
No.25
考点:链表
234. Palindrome Linked List
回文链表
其一,find mid node 使用快慢指针找到链表中点。 其二,reverse 逆序后半部分。 其三,check 从头、中点,开始比较是否相同。
12 1 21
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
ListNode* slow = head, *fast = head, *prev = nullptr;
while (fast){//find mid node
slow = slow->next;
fast = fast->next ? fast->next->next: fast->next;
}
while (slow){//reverse
ListNode* ovn = slow->next;
slow->next = prev;
prev = slow;
slow = ovn;
}
while (head && prev){//check
if (head->val != prev->val){
return false;
}
head = head->next;
prev = prev->next;
}
return true;
}
};
No.26
考点:链表
206. Reverse Linked List
反转链表
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
思路:迭代
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *prev = nullptr;
ListNode *cur = head;
while (cur)
{
ListNode *next = cur->next;
cur->next = prev;
prev = cur, cur = next;
}
return prev;
}
};
至此,easy篇结束,开启medium篇。
类别:热题HOT100 medium篇 共59道
No.27
考点:滑动窗口,字符串
3. Longest Substring Without Repeating Characters
无重复字符的最长字串
在这里插入代码片
No.28
考点:字符串
No.29
考点:字符串
No.30
考点:字符串
No.31
考点:字符串
No.32
考点:字符串
No.33
No.34
No.35
No.36
No.37
No.38
No.39
No.40
剑指offer:https://www.nowcoder.com/ta/coding-interviews?page=1 No.8
跳台阶
考点:动态规划
略
No.9
变态跳台阶
考点:归纳法、递归
class Solution {
public:
int jumpFloorII(int number) {
if (number <= 0)
return -1;
else if(number ==1)
return 1;
else
return 2*jumpFloorII(number-1);
}
};
No.10
矩形覆盖
考点:动态规划
class Solution {
public:
int rectCover(int number) {
if(number==1)
return 1;
if(number==2)
return 2;
int first =1;
int second =2;
int third =0; //正好当number非法的时候,返回0;
for(int i=3;i<=number;i++)
{
third= first+second;
first=second;
second=third;
}
return third;
}
};
No.11
二进制中1的个数
考点:位运算
略
No.12
数值的整数次方
class Solution {
public:
double Power(double base, int exponent) {
if(exponent ==0)
return 1;
if(exponent<0)
{
exponent = -exponent;
base = 1/base;
}
double res = base;
for(int i=2;i<=exponent;i++){
res *=base;
}
return res;
}
};
No.13
调整数组顺序使奇数位于偶数前面
考点:数组、排序
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路:插入排序,当前数是奇数,就往前找,遇到偶数就往它前面插。
class Solution {
public:
void reOrderArray(vector<int> &array) {
for(int i = 1; i<array.size();i++){
int tmp = array[i];
if(tmp % 2 == 1){
for(int j = i;j>0;j--){
if(array[j-1] % 2 == 0){
//swap(array[j],array[j-1]);
int t = array[j];
array[j] = array[j-1];
array[j-1] = t;
}}}}}};
No.14
链表中倒数第k个结点
考点:链表
思路:注意,走的是k-1步
eg:有3个节点,要倒数第3个,那么只能走2步。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==nullptr || k==0)
return nullptr;
ListNode* p = pListHead;
for(int i=0;i<k-1;i++)
{
if(p->next){p=p->next;}
else return nullptr;
}
ListNode* kNode =pListHead;
while(p->next)
{
p=p->next;
kNode = kNode->next;
}
return kNode;
}
};