Interview Questions: Balanced Search Trees

Balanced Search Trees

Red–black BST with no extra memory. Describe how to save the memory for storing the color information when implementing a red–black BST.

Hint: modify the structure of the BST to encode the color information.

BST需要满足 左结点L < 根结点P < 右结点R,那么这样设定:如果 L > P,那么说明L为红结点;如果 R < P,那么说明R为红结点。因此在左偏红黑树中,将一个结点标记为红色的方法是:将结点red的值变为 r e d . v a l u e = 2 ∗ p a r e n t − r e d . v a l u e red.value=2*parent-red.value red.value=2parentred.value

public class LLRB {
    private static final int LEFT = 1;
    private static final int RIGHT = 2;
    private Node root;

    public boolean search(int target) {
        Node x = root;
        int preValue = x.val;
        int flag = 0;
        while (x != null) {
            int trueValue = x.val;
            if (flag == LEFT && trueValue > preValue) {
                trueValue = 2 * preValue - trueValue;
            }
            if (target < trueValue) {
                x = x.left;
                flag = LEFT;
                preValue = trueValue;
            } else if (target > trueValue) {
                x = x.right;
            } else {
                return true;
            }
        }

        return false;
    }

    public void insert(int val) {
        insert(root, val, 0, 0);
        root.val = -1 * root.val;
    }

    private Node insert(Node x, int val, int preValue, int flag) {
        if (x == null) {
            return new Node(2 * preValue - val);
        }
        int trueValue = x.val;
        if (flag == LEFT && trueValue > preValue) {
            trueValue = 2 * preValue - trueValue;
        }
        if (val < trueValue) {
            x.left = insert(x.left, val, trueValue, LEFT);
        } else if (val > trueValue) {
            x.right = insert(x.right, val, trueValue, RIGHT);
        }

        if ((x.right != null && x.right.val > trueValue) && (x.left == null || x.left.val < trueValue)) {
            x = rotateLeft(x, trueValue, trueValue != x.val);
        }
        if (x.left != null && x.left.left != null && x.left.val > trueValue
                && x.left.left.val > (2 * (2 * trueValue - x.left.val) - x.left.left.val)) {
            x = rotateRight(x, trueValue, trueValue != x.val);
        }
        if ((x.left != null && x.left.val > trueValue) && (x.right != null && x.right.val < trueValue)) {
            flipColors(x, trueValue);
        }

        return x;
    }

    private Node rotateLeft(Node x, int preValue, boolean isRed) {
        Node y = x.right;

        if (isRed) {
            x.val = 2 * preValue - x.val;
        }
        y.val = 2 * x.val - y.val;

        x.right = y.left;
        y.left = x;
        x.val = 2 * y.val - x.val;
        if (isRed) {
            y.val = 2 * preValue - y.val;
        }

        return y;
    }

    private Node rotateRight(Node x, int preValue, boolean isRed) {
        Node y = x.left;

        if (isRed) {
            x.val = 2 * preValue - x.val;
        }
        y.val = 2 * x.val - y.val;

        x.left = y.right;
        y.right = x;
        x.val = 2 * y.val - x.val;
        if (isRed) {
            y.val = 2 * preValue - y.val;
        }

        return y;
    }

    private void flipColors(Node x, int preValue) {
        x.left.val = 2 * x.val - x.left.val;
        x.right.val = 2 * x.val - x.right.val;
        x.val = 2 * preValue - x.val;
    }

    private class Node {
        Node left, right;
        int val;

        Node(int val) {
            this.val = val;
        }
    }
}

Document search. Design an algorithm that takes a sequence of n document words and a sequence of m query words and find the shortest interval in which the m query words appear in the document in the order given. The length of an interval is the number of words in that interval.

Hint: for each word, maintain a sorted list of the indices in the document in which that word appears. Scan through the sorted lists of the query words in a judicious manner.

题目大意:给定一组n个被查找单词,和一组m个待查找单词,要求在n个被查找单词中找到一个最小区间,使得这个区间包含所有m个待查找单词,且这m个单词出现的顺序和给定的顺序一致。

解法:给每一个不同的单词开一个列表,记录该单词在n个被查找单词中出现的下标位置(有序);得到m个待查找单词对应的位置列表,从这m个列表中各挑出一个数字组成序列,要求该序列首尾之差最小,且要保证序列为递增序列。

import java.util.*;

public class Document {
    private String[] document;
    private String[] query;

    public void search() {
		// 记录满足条件的最短区间的两个端点
        // 将first设为-1有助于判断最终能否找到有效的区间
        int first = -1, last = document.length - 1;

        // 根据每个不同的单词生成对应的递增下标序列
        Map<String, Queue<Integer>> map = new HashMap<>();
        for (int i = 0; i < document.length; i++) {
            if (!map.containsKey(document[i])) {
                Queue<Integer> q = new LinkedList<>();
                q.add(i);
                map.put(document[i], q);
            } else {
                map.get(document[i]).add(i);
            }
        }

        // 摘出m个待查找单词对应的下标序列
        Queue<Integer>[] q = new Queue[query.length];
        for (int i = 0; i < query.length; i++) {
            q[i] = map.get(query[i]);
        }

        // 搜寻满足条件的区间
        OUTER:
        for (int i : q[0]) {
            int left = i, right = i;	// 记录当前区间的两个端点
            for (int j = 1; j < q.length; j++) {
                // 每次都选取各序列中满足条件的最小的位置,并出队小于这个位置的所有下标
                while (!q[j].isEmpty() && q[j].peek() <= right) {
                    q[j].poll();
                }
                if (q[j].isEmpty()) {
                    break OUTER;		// 当某一单词对应下标全出队后,可直接跳出外层循环
                } else {
                    right = q[j].peek();	// 更新当前区间的右端点
                }
            }
            // 更新最短区间的左右端点
            if (right - left  < last - first) {
                first = left;
                last = right;
            }
        }
        	
        if (first != -1) {
            System.out.println(last - first);
        } else {
            System.out.println("Not Found");
        }
    }
}

Generalized queue. Design a generalized queue data type that supports all of the following operations in logarithmic time (or better) in the worst case.

  • Create an empty data structure.
  • Append an item to the end of the queue.
  • Remove an item from the front of the queue.
  • Return the i t h i^{th} ith item in the queue.
  • Remove the i t h i^{th} ith item from the queue.

Hint: create a red–black BST where the keys are integers and the values are the items such that the i t h i^{th} ith largest integer key in the red–black BST corresponds to the i t h i^{th} ith item in the queue.

用红黑树构建的符号表来储存队列元素,key值记录入队序号,value值储存对应item。出队则找最小的序号,入队则加入一个新序号;找到第i大的元素,就是在树中找到序号第i大的结点,这与之前BST实现的符号表中的select()实现方法是一样的。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值