2021-01-20

天眼查面试-算法题

2021-01-20下午参加天眼查的视频面试,首先是来了两道算法题目和一道SQL建立索引题目。

努力了不一定会成功,但是不努力一定会失败!!!

一、将两个升序或降序未知的有序链表合并成指定升序或降序的链表

该题算是一个多考查点的题目。

考查点:

(1)判断有序链表是升序还是降序;

(2)反转链表;

(3)合并两个有序链表(同为升序或降序);Leetcode_88;

该题目按照上面三个考查点分别实现三个子函数,即可顺序完成该题目,平时的积累还是很重要的哦。

    /**
     * 将两个升序或降序未知的有序链表合并成指定升序或降序的链表
     * 属于Leetcode_21的变式题
     * 网上搜索:https://www.jianshu.com/p/dceced82ad90
     * 2021-01-20
     * 2021年第一次面试,天眼查,第一道面试题;
     * 大体思路完成,但是没有封装listIsAsc方法,欠缺一点点。
     *
     * 示例:
     * 链表A:1->3->4->11
     * 链表B:9->3->0
     * 指定:升序
     * 结果:0->1->3->3->4->9->11
     * <p>
     * 解题思路:
     * 指定升序:两个链表需要转变成升序;
     * 指定降序:两个链表要转变成降序;
     */
 
/**
     * 将两个升序降序未知的有序链表合并成指定升序或降序的链表
     */
    public ListNode mergeTwoSortedList(ListNode node1, ListNode node2, boolean isAsc) {
        //1、将两个链表转变成isAsc顺序一致的链表
        if (isAsc) {//两个链表均需要置为升序
            if (!listIsAsc(node1)) node1 = reverseList(node1);
            if (!listIsAsc(node2)) node2 = reverseList(node2);
        } else {//两个链表均需要置为降序
            if (listIsAsc(node1)) node1 = reverseList(node1);
            if (listIsAsc(node2)) node2 = reverseList(node2);
        }
        return mergeTwoSameSortedList(node1, node2, isAsc);
    }

    /**
     * 判断链表是否是升序
     */
    public boolean listIsAsc(ListNode head) {
        if (head == null) return true;
        ListNode pre = head;
        head = head.next;
        while (head != null) {
            if (head.val < pre.val) return false;
            pre = head;
            head = head.next;
        }
        return true;
    }

    /**
     * 反转链表
     */
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode pre = head;
        ListNode curr = head.next;
        head.next = null;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = pre;
            pre = curr;
            curr = next;
        }
        return pre;
    }


    /**
     * head1和head2已经按照isAsc排序
     * isAsc=true,则head1和head2均升序;
     * isAsc=false,则head1和head2均降序;
     */
    public ListNode mergeTwoSameSortedList(ListNode head1, ListNode head2, boolean isAsc) {
        if (head1 == null) return head2;
        if (head2 == null) return head1;
        //是否head1优先:isAsc=true,小值优先,反之,大值优先
        boolean node1First = isAsc ? (head1.val < head2.val) : (head1.val > head2.val);
        if (node1First) {
            head1.next = mergeTwoSameSortedList(head1.next, head2, isAsc);
            return head1;
        } else {
            head2.next = mergeTwoSameSortedList(head1, head2.next, isAsc);
            return head2;
        }
    }

class ListNode {
    public ListNode next;
    public int val;
    public ListNode(int val) {
        this.val = val;
    }
}

  /******************测试*********************/
    @Test
    public void test() {
        boolean[] isAsc = new boolean[]{true, false};
        for (int i = 0; i < 2; i++) {
            ListNode head1 = new ListNode(1);
            ListNode node1_2 = new ListNode(3);
            ListNode node1_3 = new ListNode(4);
            ListNode node1_4 = new ListNode(11);
            head1.next = node1_2;
            node1_2.next = node1_3;
            node1_3.next = node1_4;
            ListNode head2 = new ListNode(9);
            ListNode node2_2 = new ListNode(3);
            ListNode node2_3 = new ListNode(0);
            head2.next = node2_2;
            node2_2.next = node2_3;
            LinkedListUtils.print(mergeTwoSortedList(head1, head2, isAsc[i]));//打印函数自己实现吧
        }
    }


二、反序列化完全二叉树

 /**
     * 2021-01-20下午面试第二题(简单)完成
     * 完全二叉树序列化后:ABCDEFGHIJKLMNOPQ;
     * 将其转换成树结构。
     *          A
     *      B       C
     *    D   E   F   G
     *   H I J K L M N O
     *  P Q
     */

    public TreeNode transferToBinaryTree(char[] chars) {
        if (chars == null || chars.length == 0) return null;
        TreeNode root = new TreeNode(chars[0]);
        Deque<TreeNode> deque = new LinkedList<>();
        deque.add(root);
        int i = 1;
        while (!deque.isEmpty() && i < chars.length) {
            TreeNode node = deque.poll();
            if (i < chars.length) {
                node.left = new TreeNode(chars[i++]);
                deque.add(node.left);
            }
            if (i < chars.length) {
                node.right = new TreeNode(chars[i++]);
                deque.add(node.right);
            }
        }
        return root;
    }

    @Test
    public void test() {
        TreeNode root = transferToBinaryTree("ABCDEFGHIJKLMNOPQ".toCharArray());
        List<ArrayList<Integer>> arrayLists = new TraversalByLevelOrZigZag().traversalByEveryLevel(root);
        for (ArrayList<Integer> arrayList : arrayLists) {
            List<Character> charList = new ArrayList<>();
            arrayList.forEach(item -> charList.add((char)item.intValue()));
            System.out.println(JSON.toJSONString(charList));
        }
    }

三、如何建立索引更高效

select e,f from table_1 where a = 3 and b=4 and c != 5 sorted by e limit 100

回答:建立联合索引 a,b,e,f 。 (并没有明确是否正确,如果有更好方式,请指正。)

因为查询a、b都是固定值,e是排序字段,c是不等于无法走索引,查询字段e和f,因此建立a,b,e,f联合索引最高效。

知识点:前缀索引,覆盖索引。  

紧接着问了:底层的B+树,聚簇索引、二级索引等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值