反转链表
- 一个是暴力,直接从头到尾遍历一遍,同时用栈记录每一个节点,最后弹栈、把弹出的节点穿成一个链表并返回
- (双指针)遍历一遍原链表,同时用头插法构建得到一个新的链表
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;
}
遇到的问题: 经典的做题心情->我懂那个意思但是没写出来,还写的太少
-
对于指针的初始化,如果只需要进行遍历链表的操作,那只创建
ListNode *p;就行,注意两个指针一前一后的顺序+循环终止的条件 -
即使对于遍历链表来说,只是一个单纯的指针,但指针是可以直接修改所指向的那块内存的
// head是链表头指针,链表为[1,2,3,4] ListNode* p = head; p = 2; // 此时链表为[2,2,3,4] p = null; // 此时索引不到后续的链表了 -
用画图辅助分析指针(贼有效)
对称二叉树
- 每个左节点的左孩子与对应右节点的右儿子相同(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);
}
遇到的问题:
- 不需要在
_isSym()的函数的if(L && R)里面再判断一次左右儿子的值,因为函数开头就已经衡量过L和R了