• 算法题


    2016-12-04

    纪念解决第一个算法题:TWO SUM

    第一种解法:

    public class twosum2 {
    
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
            twosum2 twosum = new twosum2();   //实例化这个类,第一个是类名,空格后面是实例化的类名
            int[] nums = new int[4];        //输入数组
            int target = 6;
            nums[0] = 1;
            nums[1] = 3;
            nums[2] = 4;
            nums[3] = 5;  
            twosum.Twosum(nums, target);     //调用方法,第一个是实例化的类名,。后面是调用函数名 
            int[] result = twosum.Twosum(nums, target);       //使用调用方法的返回值
            for(int i = 0; i < twosum.Twosum(nums, target).length; ++i){
                System.out.println(result[i]);
            }
    
        }
    //以上是测试部分,以下是算法部分
        public int[] Twosum(int[] nums, int target) {
            int[] result = new int [2];
            for (int i = 0; i < nums.length; i++) {
                for (int j = i + 1; j < nums.length; j++) {
                    if (nums[i] + nums[j] == target) {                    
                        result[0] = i + 1;
                        result[1] = j + 1; 
                        break;                    
                    }
                }
            }
            return result;
        }
        
    }

     第二种解法:

    public class Solution {
        /*
         * @param numbers : An array of Integer
         * @param target : target = numbers[index1] + numbers[index2]
         * @return : [index1 + 1, index2 + 1] (index1 < index2)
         */
    public static int[] twoSum(int[] numbers, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        //target = numbers[i] + numbers[j]
        //target - numbers[i] = numbers[j] ==>找target变为找numbers[j]
        //利用HashMap记录数值的位置,先用map.put写入数据,并且任然记录i的位置
        //判断后出现的值(if语句内的)是否曾出现过,就是在已有的map内,如果存在就表示目前这个值和之前的某个值之和为target,
        //而且之前的值得位置记录在map中,就是map.get(numbers[i])
        for (int i = 0; i < numbers.length; i++) {
            if (map.get(numbers[i]) != null) {
                int[] result = {map.get(numbers[i]), i};
                return result;
            }
            map.put(target - numbers[i], i);
        }
        int[] result = {};
        return result;
    }

    }

     2016-12-05

    字符串查找

    自己的第一种解法:

    主要需要注意的是要考虑 source字符串和target字符串分别是null的情况,当任意一个字符串是null时,都无法调用方法,所以在调用方法的时候一定要分情况考虑。 

    public int strStr(String source, String target) {
            if (source == null || target == null) {
                return -1;
            } else {
                  int x = source.indexOf(target);
                  return x;
            }
        }
    View Code

     优解

    注意最里面是对target字符串循环检测,还有注意用不等于!=来做循环条件。

    class Solution {
        /**
         * Returns a index to the first occurrence of target in source,
         * or -1  if target is not part of source.
         * @param source string to be scanned.
         * @param target string containing the sequence of characters to match.
         */
        public int strStr(String source, String target) {
            if (source == null || target == null) {
                return -1;
            } else {
                int n = target.length();
                int m = source.length();
                int j = 0;
                for (int i = 0; i < m - n + 1; i++) {
                    for (j = 0; j < n; j++) {
                        if (source.charAt(i + j) != target.charAt(j)) {
                        break;
                        }
                    }
                    if (j == n) {
                        return i;
                    }
                }
                return -1;
              }
        }
    }
    View Code

     2016-12-07

    Last position of target

    return result 语句运行之后直接结束子方法的解析返回主方法,等同于一个break。

    注意理解二分法,无限逼近的思想,还有注意null和目标处于数组的收尾位置的特殊情况,数组中不存在目标数也要有输出(-1)。

    但是我有个疑问,为什么在测试算法的时候,一定要在最后加上一个 return (xx): 因为 int 型方法,需要你返回一个整形,即便是你考虑了所有情况,但是还是要满足java 的语法要求。

    说白了就是你考虑到最后一种情况时,就不用写出来了,直接把结果return 回去不就好了?

    public class Solution {
        /**
         * @param nums: An integer array sorted in ascending order
         * @param target: An integer
         * @return an integer
         */
        public int lastPosition(int[] nums, int target) {
            if (nums == null || nums.length == 0) {
                return -1;
            }
            int start = 0;
            int end = nums.length - 1;
            while (start + 1 < end) {
                int mid = start + (end - start) / 2;
                if (nums[mid] == target) {
                    start = mid;
                } else if (nums[mid] < target) {
                    start = mid;
                    // or start = mid + 1
                } else {
                    end = mid;
                    // or start = mid - 1
                }
            }
            if (nums[end] == target) {
                return end;
            }
            if (nums[start] == target) {
                return start;
            }
            return -1;
        }
    }
    View Code

     Search and insert

    同样是二分法,需要注意的是要考虑目标数大于等于数组的最后一个数;还有小于等于第一个数的情况,这些特殊情况要单独用if语句表示出来。

    public class Solution {
        /**
         * param A : an integer sorted array
         * param target :  an integer to be inserted
         * return : an integer
         */
        public int searchInsert(int[] A, int target) {
            if (A == null || A.length == 0) {
                return 0;
            }
            int start = 0;
            int end = A.length - 1;
            while (start + 1 < end) {
                int mid = start + (end - start) / 2;
                if (A[mid] == target) {
                    return mid; //System.out.println(mid);//start = mid;
                } else if (A[mid] < target) {
                    start = mid;
                    // or start = mid + 1
                } else {
                    end = mid;
                    // or start = mid - 1
                }
            }
            if (A[end] < target) {
                return end + 1;
            } else if (A[end] == target) {
                return end;
            }
            if (A[start] < target && A[end] > target) {
                return start + 1;
            }
            if (A[start] > target || A[start] == target) {
                return 0;
            }
            return 0;
        }
    }
    View Code

     2016-12-08  00:34:39

    binarySearch

    纪念第一次lintcode算法一次性AC。

    这一问题注意是寻找第一个target出现的位置,而且是升序数组,所以直接考虑用小于做判断,而且target一定是在二分法寻找的最终两个相邻的整数之中的一个,判断并返回其位置,或者不存在那么返回-1。

    class Solution {
        /**
         * @param nums: The integer array.
         * @param target: Target to find.
         * @return: The first position of target. Position starts from 0.
         */
        public int binarySearch(int[] nums, int target) {
            if (nums == null || nums.length == 0) {
                return -1;
            }
            int start = 0;
            int end = nums.length - 1;
            int mid;
            while (start < end - 1) {
                mid = start + (end - start) / 2;
                if (nums[mid] < target) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
            if (nums[end] == target) {
                return end;
            }
            if (nums[start] == target) {
                return start;
            }
            return -1;
        }
    }
    View Code

     2016-12-08  18:28:09

    find peak

    lintcode和leetcode对于这个题目的要求不一样,所以分别给出下面第一种和第二种算法。

    lintcode给出的约束条件更多,考虑的范围小一点,算法就相对简单一点。

    class Solution {
        /**
         * @param A: An integers array.
         * @return: return any of peek positions.
         */
        public int findPeak(int[] A) {
            int start;
            int end = A.length - 1;
            for (start = 1; start < end; start++) {
                if (A[start] > A[start + 1]) {
                    return start;
                }
            }
            return 1;
        }
    }
    View Code
    public class Solution {
        public int findPeakElement(int[] nums) {
            int start;
            int end = nums.length - 1;
            if (nums.length == 1) {
                return 0;
            } else {
                for (start = 0; start < end; start++) {
                    if (nums[start] > nums[start + 1]) {
                    return start;
                    } 
                }
            }
            return end;        
        }
    }
    View Code

     2016-12-08  22:52:44

    first Bad Version

    二分法,循环到二分法最后一步,两个数之间判断然后取一个出来返回,很像binarySearch。

    class Solution {
        /**
         * @param n: An integers.
         * @return: An integer which is the first bad version.
         */
        public int findFirstBadVersion(int n) {
            int start = 1;
            int end = n;
            while (start < end - 1) {
                int mid = start + (end - start) / 2;
                if (SVNRepo.isBadVersion(mid)) {
                    end = mid;
                } else {
                    start = mid;
                }
            }
            if (SVNRepo.isBadVersion(start)) {
                return start;
            }
            return end;
        }
    }
    View Code

     2016-12-09  00:31:59

    search Matrix

    这个要好好理解一下时间复杂度,我自己的解法超出限制时间,时间复杂度不好。

    public class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            if (matrix == null || matrix.length == 0) {
                return false;
            }
            if (matrix[0] == null || matrix[0].length == 0) {
                return false;
            }
            int row = matrix.length;
            int column = matrix[0].length;
            int start = 0;
            int end = row * column - 1;
            while (start + 1 < end) {
                int mid = start + (end - start) / 2;
                int number = matrix[mid / column][mid % column];
                if (number == target) {
                    return true;
                } else if (number < target) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
            if (matrix[start / column][start % column] == target) {
                return true;
            } else if (matrix[end / column][end % column] == target) {
                return true;
            }
            return false;
        }
    }
    View Code

     2017-01-13 16:56:08

    Subsets

    第一次接触ArrayList(动态数组)

    public class Solution {
        public ArrayList<ArrayList<Integer>> subsets(int[] num) {
            ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
            if(num == null || num.length == 0) {
                return result;
            }
            ArrayList<Integer> list = new ArrayList<Integer>();
            Arrays.sort(num);  
            subsetsHelper(result, list, num, 0);
    
            return result;
        }
    
    
        private void subsetsHelper(ArrayList<ArrayList<Integer>> result,
            ArrayList<Integer> list, int[] num, int pos) {
    
            result.add(new ArrayList<Integer>(list));
    
            for (int i = pos; i < num.length; i++) {
    
                list.add(num[i]);
                subsetsHelper(result, list, num, i + 1);
                list.remove(list.size() - 1);
            }
        }
    }
    View Code
  • 相关阅读:
    Postman安装出错.NET Framework 4.5 failed to install
    给小白的资源
    windows update自启动解决方法
    Fragment简介及使用
    samba修复
    我的Android知识结构图——20200507停止更新,后续通过标签或分类继续完善结构图
    Android_适配器(adapter)之BaseAdapter
    Android_适配器(adapter)之SimpleAdapter
    Android_适配器(adapter)之ArrayAdapter
    Linux部分场景非常有用的命令集1_chattr&ldd&xargs&screen&ssh&磁盘&du
  • 原文地址:https://www.cnblogs.com/xuhaojun/p/6130325.html
Copyright © 2020-2023  润新知