part2-HOT100+剑指Offer

leetcode:https://leetcode-cn.com/problemset/algorithms/
类别:热题HOT100 easy篇 共26道
No.21 -------------- 可将滑动窗口作为一个章节来看啦。。。
标签:哈希表,滑动窗口
438. Find All Anagrams in a String
找异位词的字串起始索引
异位词:字母相同,但排列不同的字符串
思想:滑动窗口通用思想解决字串问题,双指针技巧(窗口的左右界限)
这道题要找长度相同的子串,也就是「字母异位词」嘛。

class Solution {
public:
   
    vector findAnagrams(string s, string t) {
    // 用数组记录答案
    vector res;
    int left = 0, right = 0;
    unordered_map needs;
    unordered_map 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 &array) {
    for(int i = 1; i0;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;inext){p=p->next;}
            else return nullptr;
        }
        ListNode* kNode =pListHead;
        while(p->next)
        {
            p=p->next;
            kNode = kNode->next;
        }
        return kNode;
    }
};

你可能感兴趣的:(刷刷题)