算法题

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
原文地址:https://www.cnblogs.com/xuhaojun/p/6130325.html