zoukankan      html  css  js  c++  java
  • 面试题随记一

    刚经历某互联网公司第一轮面试,面试题为三道编程题,三十分钟内完成,完成两道,剩余一道由于时间不够所以就写出了思路,在这里做一个记录。具体算法思想见代码注解。

    数组操作,求:交集、并集、差集

    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 数组操作,求:交集、并集、差集
     *
     * 在能够表达算法思想的前提下尽量简化一下情况,所以这里就假定数组内元素不重复
     */
    public class ArrayOperation {
    
        @Test
        public void test() {
            int[] arr1 = new int[]{1,3,6,9,8};
            int[] arr2 = new int[]{1,3,6,11,10};
            // 排序测试
            sort(arr1,0,arr1.length - 1);
            sort(arr2,0,arr2.length - 1);
    
            // 交集
            List<Integer> intersectionResult = intersection(arr1,arr2);
            // 并集
            List<Integer> unionResult = union(arr1,arr2);
            // 差集
            List<Integer> differenceResult = difference(arr1,arr2);
        }
    
        /**
         * 快排
         *
         * 思路:挖坑填数+分治法
         */
        private void sort(int[] arr,int low,int high) {
            if (low >= high) {
                return;
            }
            int left = low,right = high;
            int movedVal = arr[left];
            while (left < right) {
                while (left < right && arr[right] >= movedVal) {
                    right--;
                }
                arr[left] = arr[right];
                while (left < right && arr[left] <= movedVal) {
                    left++;
                }
                arr[right] = arr[left];
            }
            arr[left] = movedVal;
            sort(arr,low,left - 1);
            sort(arr,left + 1,high);
        }
    
        /**
         * 交集
         *
         * 思路:将两个有序数组遍历,相等则加入结果中,不等较小值的数组索引加1,直到任意一个数组遍历完成
         */
        private List<Integer> intersection(int[] arr1,int[] arr2) {
            sort(arr1,0,arr1.length - 1);
            sort(arr2,0,arr2.length - 1);
            List<Integer> result = new ArrayList<>();
            int index1 = 0,index2 = 0;
            int len1 = arr1.length,len2 = arr2.length;
            while (index1 < len1 && index2 < len2) {
                if (arr1[index1] == arr2[index2]) {
                    result.add(arr1[index1]);
                    index1++;
                    index2++;
                } else if (arr1[index1] > arr2[index2]) {
                    index2++;
                } else {
                    index1++;
                }
            }
            return result;
        }
    
        /**
         * 并集
         *
         * 思路:依次遍历两个数组,相等索引数据加入到结果中一次,两个索引同时加1,不相等的将较小值加入结果同时索引加1;当任意一个数组遍历完后,将另一个数组剩余元素添加进结果;
         */
        private List<Integer> union(int[] arr1,int[] arr2) {
            int len1 = arr1.length,len2 = arr2.length;
            sort(arr1,0,len1 - 1);
            sort(arr2,0,len2 - 1);
            int index1 = 0,index2 = 0;
            List<Integer> result = new ArrayList<>();
            while (index1 < len1 && index2 < len2) {
                if (arr1[index1] == arr2[index2]) {
                    result.add(arr1[index1]);
                    index1++;
                    index2++;
                } else if (arr1[index1] > arr2[index2]) {
                    result.add(arr2[index2]);
                    index2++;
                } else {
                    result.add(arr1[index1]);
                    index1++;
                }
            }
            while (index1 < len1) {
                result.add(arr1[index1]);
                index1++;
            }
            while (index2 < len2) {
                result.add(arr2[index2]);
                index2++;
            }
            return result;
        }
    
        /**
         * 差集
         *
         * 思路:依次遍历两个数组,值相等索引同时加1忽略相同值;不同值加入较小值并将索引加1,直到任意一个数组遍历完成;然后将另一个素组中剩余元素加进结果中。
         */
        private List<Integer> difference(int[] arr1,int[] arr2) {
            int len1 = arr1.length,len2 = arr2.length;
            int index1 = 0,index2 = 0;
            List<Integer> result = new ArrayList<>();
            while (index1 < len1 && index2 < len2) {
                if (arr1[index1] == arr2[index2]) {
                    index1++;
                    index2++;
                } else if (arr1[index1] > arr2[index2]) {
                    result.add(arr2[index2]);
                    index2++;
                } else {
                    result.add(arr1[index1]);
                    index1++;
                }
            }
            while (index1 < len1) {
                result.add(arr1[index1]);
                index1++;
            }
            while (index2 < len2) {
                result.add(arr2[index2]);
                index2++;
            }
            return result;
        }
    }
    

    求一个数组中的连续子列表的最大和

    import org.junit.Test;
    
    /**
     * 求一个数组中的连续子列表的最大和
     */
    public class SubListSum {
    
        @Test
        public void test() {
            int[] arr = new int[]{1,2,3,6,7,8,5,6};
            // 测试结果 21
            int sum = subListSum(arr);
        }
    
        /**
         * 思路:使用动态规划
         * 初始dp[0] = arr[0]
         * 如果arr[i] = arr[i - 1],则dp[i] = dp[i - 1] + arr[i]
         * 否则dp[i] = arr[i]
         */
        private int subListSum(int[] arr) {
            int[] dp = new int[arr.length];
            dp[0] = arr[0];
            int sum = dp[0];
            for (int i = 1;i < arr.length;i++) {
                if (arr[i] == arr[i - 1] + 1) {
                    dp[i] = dp[i - 1] + arr[i];
                } else {
                    dp[i] = arr[i];
                }
                sum = Math.max(sum,dp[i]);
            }
            return sum;
        }
    }
    

    求元素首次出现下标

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 一个可能多次重复元素的数组,然后找出给定值首次出现的下标,如果未出现返回-1
     */
    public class FirstSubscript {
    
        /**
         * 整体思路:将元素和对应下标组成一对,不断的插入一个列表中生成一个有序列表,然后查询的时候使用二分查找
         *
         * 进阶思路:将元素和对应小标组成一对,维护一个红黑树,使用红黑树进行插入和查找
         */
        public static void main(String[] args) {
            int[] arr = new int[]{1,1,2,1,2,2,7,8,9,9,8,7};
            FirstSubscript fs = new FirstSubscript(arr);
            // 7首次出现下标 6
            int result1 = fs.queryFirstIndex(7);
            // 20未出现 -1
            int result = fs.queryFirstIndex(20);
        }
    
        private List<Entry> list = new ArrayList<>();
    
        public FirstSubscript(int[] arr) {
            for (int i = 0;i < arr.length;i++) {
                int val = arr[i];
                int li = 0;
                while (li < list.size() && list.get(li).val < val) {
                    li++;
                }
                if (li >= list.size() || list.get(li).val != val) {
                    if (li >= list.size()) {
                        list.add(new Entry(val,i));
                    } else {
                        list.set(li,new Entry(val,i));
                    }
                }
            }
        }
    
        /**
         * list进行二分查找
         */
        private int queryFirstIndex(int val) {
            int left = 0,right = list.size() - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                int tempVal = list.get(mid).val;
                if (tempVal == val) {
                    return list.get(mid).index;
                } else if (tempVal > val) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return -1;
        }
    
        private class Entry {
            int val;
            int index;
    
            Entry(int val,int index) {
                this.val = val;
                this.index = index;
            }
        }
    }
    
    
  • 相关阅读:
    使用FolderBrowserDialog组件选择文件夹
    使用OpenFileDialog组件打开多个文
    使用OpenFileDialog组件打开对话框
    获取弹出对话框的相关返回值
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1137 Final Grading (25 分)
    PAT 甲级 1137 Final Grading (25 分)
  • 原文地址:https://www.cnblogs.com/mrxiaobai-wen/p/14968534.html
Copyright © 2011-2022 走看看