109. Convert Sorted List to Binary Search Tree

来源:互联网 发布:淘宝店铺没有自然流量 编辑:程序博客网 时间:2024/06/06 12:54

题目:

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.


题意:

给定一个按升序排列的单链表,将其转换为高度平衡的二叉搜索树。


思路一:

将有序链表存在一个数组里。根据每次访问中间节点当做根节点,递归调用左右子树节点。

代码:30ms

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; *//** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    TreeNode* sortedListToBST(ListNode* head) {        if(!head) return NULL;                vector<int> tmp;        while(head){  //将链表转换为数组            tmp.push_back(head->val);            head = head->next;        }        return sortedArrayTree(tmp, 0, tmp.size()-1);    }        TreeNode *sortedArrayTree(vector<int> &arr, int start, int end){        if(start > end) return NULL;                TreeNode *root = new TreeNode(arr[(start+end)/2]); //取数组中间元素作为根节点                root->left = sortedArrayTree(arr, start, (start+end)/2-1);        root->right = sortedArrayTree(arr, (start+end)/2+1, end);        return root;    }};
思路二:

定义两个分别为一快一慢的节点变量,慢节点每次向前一步,快节点每次向前两步,当快节点到达末尾时,慢节点到链表中间位置,慢节点值即为二叉搜索树的根节点值,之后依次递归左右子树。

代码:1ms

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { val = x; } * } *//** * Definition for a binary tree node. * public class TreeNode { *     int val; *     TreeNode left; *     TreeNode right; *     TreeNode(int x) { val = x; } * } */public class Solution {    public TreeNode sortedListToBST(ListNode head) {        return rec(head, null);    }        public TreeNode rec(ListNode start, ListNode end){        if(start==end) return null;                ListNode p = start, q = start;        while(q!=end && q.next!=end){  //找到链表中间值            p = p.next;            q = q.next.next;        }                TreeNode root = new TreeNode(p.val);  //链表中间值作为根节点        root.left = rec(start, p);        root.right = rec(p.next, end);                return root;    }}

思路三:

先求出链表长度,将链表长度作为参数传递进递归函数,每次寻找链表中点时,只需要新定义的指针向前移动一般链表长度即可,将找到的节点值作为根源上节点值,之后递归调用左右子树。

代码:28ms

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; *//** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    TreeNode* sortedListToBST(ListNode* head) {        int n = 0;        ListNode *p = head;        while(p!=NULL){  //得到链表长度            n++;            p = p->next;        }        return sortedListToBST(head, n);    }        TreeNode *sortedListToBST(ListNode *head, int n){        if(head==NULL || n==0) return NULL;                ListNode *p = head;        for(int i=1; i<(n+1)/2; ++i){  //每次找到传入长度的中间值            p = p->next;        }        TreeNode *root = new TreeNode(p->val);  //将中间值作为根节点        root->left = sortedListToBST(head, (n+1)/2-1);        root->right = sortedListToBST(p->next, n-(n+1)/2);        return root;    }};
思路四:

以上三种方法都是自顶向下生成的二叉树,本方法采用自底向上的方式生成二叉树,迭代递归时,根据链表顺序依次将链表值填入二叉搜索树中。

代码:1ms

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { val = x; } * } *//** * Definition for a binary tree node. * public class TreeNode { *     int val; *     TreeNode left; *     TreeNode right; *     TreeNode(int x) { val = x; } * } */public class Solution {        static ListNode currentHead = null;        public TreeNode sortedListToBST(ListNode head) {        if(head==null) return null;        currentHead = head;        int len = 0;        while(head!=null){  //获取链表长度            len++;            head = head.next;        }        return sortedListToBST(0, len-1);    }        public TreeNode sortedListToBST(int start, int end){        if(start>end) return null;                int mid = start + (end-start)/2;         TreeNode left = sortedListToBST(start, mid-1); //生成左子树        TreeNode root = new TreeNode(currentHead.val);         root.left = left;        currentHead = currentHead.next;  //链表后移        root.right = sortedListToBST(mid+1, end);   //生成右子树        return root;    }}

0 0
原创粉丝点击