面试题 02.03. 删除中间节点
注意本题不是给链表的头结点和要删除节点的值,而是只给了要删除的节点,也即只能访问该节点及其之后的链表部分。
根据提示,使删除该元素之后的链表看起来像是某个样子(即并非真的是改成某个样子)所以考虑把给定的节点之后中每个节点的值赋给前一个节点。并不是说给定头结点找正好处于中间位置的节点(应该用快慢指针)
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
面试题 02.06. 回文链表
可以先快慢指针找到中间节点然后翻转后半部分链表,双指针一前一后进行比较,染回再把后半段链表反转回来,以达到空间复杂度O1
面试题 17.12. BiNode
二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点)。实现一个方法,把二叉搜索树转换为单向链表,要求依然符合二叉搜索树的性质,转换操作应是原址的,也就是在原始的二叉搜索树上直接修改。
返回转换后的单向链表的头节点。
class Solution {
public:
TreeNode* temp;
void inorder(TreeNode* root)
{
if(root == nullptr) return ;
inorder(root->left);
temp->right = root;
root->left = nullptr; //左子树赋空
temp = root; // 向后移动
inorder(root->right);
}
TreeNode* convertBiNode(TreeNode* root) {
// 在遍历中,实现二叉搜索树转换为单向链表
TreeNode* ans = new TreeNode(-1); // new一个带有头结点的链表,
temp = ans;
inorder(root);
return ans->right;
}
};
注意本题为二叉搜索树,想到其中序遍历为递增序列的特点采用递归的方法,
①先递归root左
②对于中间节点root的处理:
定义一个pre节点用于生成新的二叉树,pre的右子树指向root,然后令root的左子树置空,pre转而指向root
③再递归root的右子树
由于是二叉搜索树,所以可以保证按中序递归,将每个节点以root的身份接到新的树的右侧形成的新树是类似单叉树,类似单链表的样子。
由中序序列递归的性质可知,虽然第一个读进去的节点时根节点,但第一个链接到新设者的头结点右侧的是整个二叉搜索树最左下角的节点。