LeetCode 日记 Day 3

一、刷题

题号2 两数相加

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

自己的做法

这个题目比较眼熟,和数据结构课上的多项式相加的习题差不多,我借助这道题学习了一下C++中的指针。
我做题时的主要思路是对应每位进行遍历,考虑carry位。
下面是我自己的代码:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode* p = new ListNode(-1);
    ListNode* h = p;
    bool carry = false;
    while(!(l1 == NULL && l2 == NULL)){
        int sum = 0;
        if (l1 != NULL){
            sum = sum + l1->val;
            l1 = l1->next;
        }

        if (l2 != NULL) {
            sum = sum + l2->val;
            l2 = l2->next;
        }
        if (carry) sum++;
        h->next = new ListNode(sum % 10);
        h = h->next;
        carry = sum >= 10;
    }
    if (carry) {
        h->next = new ListNode(1);
    }
    return p->next;
}

在我LeetCode的评论区里找到了与我相似的写法,有一个评论指出一开始创建的表头节点没有释放,调用次数多了会造成溢出的问题。针对这个问题,可以在最后改为
preDetele = p; p = p -> next; detele preDelete; return p;来手动释放该节点。

题号3 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

自己的想法

用两个指针指向字符串中的位置,右边的指针不断增大,当右指针指向的字符已经在子串中出现过时,就将左指针不断向右移动,直到两个指针中间的子串无重复字母为止。
在具体实现的时候,我用了map来实现这个查找重复的功能,用字符作为key,用字符的下标作为value。
下面是我自己的代码:

int lengthOfLongestSubstring(string s) {
    if (s.length() == 0) return 0;
    if (s.length() == 1) return 1;
    int len = s.length();
    unordered_map  dic;
    int maxLength = 0;
    int left = 0;
    for (int i = 0 ; i < len; i++){
        if(dic.count(s[i])){
            //出现重复字符
            int c = dic[s[i]];//取出对应字符的下标
            left = max(left,c+1);//将左指针移动到重复字符之后
            dic.erase(s[i]);//把重复的字符从map中删除
        }
        dic.insert(pair(s[i],i));
        maxLength = max(maxLength,i - left + 1);
    }
    return maxLength;
}

这种方法被称为滑动窗口,是解决字符串子串问题中常见的想法。

STL中的queue

在解决题号3的问题时,我一开始想使用队列来表示子串,于是学习了C++STL中queue类的使用方法。

#include //引用queue类
常用方法:
front():返回队首元素的引用。
back():返回队尾元素的引用。
push():在队尾加入一个新元素。
pop():删除队尾元素。
empty():队列是否为空。
size():返回容器的大小。
swap(queue &other_q):将当前 queue 中的元素和参数 queue 中的元素交换。它们需要包含相同类型的元素。

最后没有使用queue的原因是queue类不支持查找队列中的元素。

STL中的map

于是想到用Hash_Map来做查找,这样查询的速度也是最快的,时间复杂度为O(1)。
c++中map的key都是唯一的,而map类中是按照key有序排列的,unordered_map则是无序的。

C++中map类的使用与构造

使用:#include
构造:map hash_map;
下面是一些常用的函数:

插入:有三种方法
1.insert(pair())
2.insert(map:: value_type(key,value))
3.hash_map[key] = value;
  注意:当我们想覆盖一个key对应的value时,只能用第三种方法进行更改。
查找:有两种方法
1.count(key),返回的是键值对出现的次数,而map中的key都是唯一的,所以只会返回0或1。
2.find(key):当所查找的关键key出现时,它返回一个迭代器,指向数据所在对象的位置;如果沒有,返回的迭代器与end函数的值相同。
删除元素:
1.erase(key):如果成功删除会返回1,否则返回0。
其他基本函数:
1.size()::返回容器大小。
2.begin():返回指向开头元素的迭代器。
3.end():返回指向末尾元素的迭代器。
4.clear():删除所有元素。
5.empty():返回是否为空。
6.size():返回容器中的元素个数。

你可能感兴趣的:(LeetCode 日记 Day 3)