day5

74 阅读2分钟

反转链表

  • 一个是暴力,直接从头到尾遍历一遍,同时用栈记录每一个节点,最后弹栈、把弹出的节点穿成一个链表并返回
  • (双指针)遍历一遍原链表,同时用头插法构建得到一个新的链表
    ListNode* reverseList(ListNode* head) {
        if(!head) return head;
        // 遍历链表一遍时采用头插法
        ListNode* p = nullptr;
        while(head){
            auto tem = head->next;
            head->next = p;
            p = head;
            head = tem;
        }
        return p;
    }

遇到的问题: 经典的做题心情->我懂那个意思但是没写出来,还写的太少

  1. 对于指针的初始化,如果只需要进行遍历链表的操作,那只创建ListNode *p;就行,注意两个指针一前一后的顺序+循环终止的条件

  2. 即使对于遍历链表来说,只是一个单纯的指针,但指针是可以直接修改所指向的那块内存的

    // head是链表头指针,链表为[1,2,3,4]
    ListNode* p = head;
    p = 2; // 此时链表为[2,2,3,4]
    p = null; // 此时索引不到后续的链表了
    
  3. 用画图辅助分析指针(贼有效)

对称二叉树

  • 每个左节点的左孩子与对应右节点的右儿子相同(L->left == R->right && L->right == R->left)。除了树根节点(也就是最顶上的节点),下面的都是传入两个对称节点进行递归
  • 层序遍历,用双端队列,每一层都用两个指针,检查是否对称
bool _isSym(TreeNode* L, TreeNode* R){
        bool outSide = true;
        bool inSide = true;
        if((L==NULL && R!=NULL) || (R==NULL && L!=NULL)) return false;
        if(L && R){
            if(L->val != R->val) return false;
            outSide = _isSym(L->left, R->right);
            inSide = _isSym(L->right, R->left);
​
        } else return true;
        return outSide && inSide;
    }
    bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        return _isSym(root->left, root->right);
    }

遇到的问题:

  1. 不需要在_isSym()的函数的if(L && R)里面再判断一次左右儿子的值,因为函数开头就已经衡量过L和R了