博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Chapter one
阅读量:4325 次
发布时间:2019-06-06

本文共 10060 字,大约阅读时间需要 33 分钟。

1.strstr(字符串查找)

对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1

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) {        // write your code here        if (source == null || target == null) {            return -1;        }        for (int i = 0; i < source.length() - target.length() + 1; i++) {            int j = 0;            for (j = 0; j < target.length(); j++) {                if (target.charAt(j) != source.charAt(i + j)) {                    break;                }            }            if (j == target.length()) {                return i;            }        }        return -1;    }}
View Code

思路:双重循环即可解决。注意第一重循环i的结束条件:source.length() - target.length() + 1。import java.lang.String

2.subsets(子集)

给定一个含不同整数(这些整数不重复)的集合,返回其所有的子集。子集中的元素排列必须是非降序的,解集必须不包含重复的子集。

class Solution {    /**     * @param S: A set of numbers.     * @return: A list of lists. All valid subsets.     */    public ArrayList
> subsets(int[] nums) { // write your code here ArrayList
> results = new ArrayList
>(); if (nums == null) { return results; } if (nums.length == 0) { results.add(new ArrayList
()); return results; } Arrays.sort(nums); helper(results, new ArrayList
(), 0, nums); return results; } private void helper(ArrayList
> results, ArrayList
subset, int startIndex, int[] nums) { //深度拷贝,不new的话最后results里面的每个元素都是相同的list,所以需要new来保存临时的list到results中。 results.add(new ArrayList
(subset)); for (int i = startIndex; i < nums.length; i++) { subset.add(nums[i]); helper(results, subset, i + 1, nums); //最后一个位置的元素删除,回溯到上一个节点 subset.remove(subset.size() - 1); } }}
View Code

思路:题目中包含“所有可能.......”,90%使用深度优先搜索解决。注意由于子集中的元素排列是非降序,所以先排序。又由于题目返回的是[[...],[...],...]所以对nums == null(null指向一个空地址)和nums.length == 0(有一个对象但为空)分别处理,前一种情况直接返回results,后一种情况results.add(new ArrayList<Integer>())后再返回results.

另一种解法: import java.util.ArrayList; import java.util.Arrays;

class Solution {    /**     * @param S: A set of numbers.     * @return: A list of lists. All valid subsets.     */    public ArrayList
> subsets(int[] nums) { // write your code here ArrayList
> results = new ArrayList
>(); ArrayList
subset = new ArrayList
(); results.add(subset); if (nums == null || nums.length == 0) { return results; } Arrays.sort(nums); for (int i = 0; i < nums.length; i++) { ArrayList
> tempResults = new ArrayList
>(results); for (ArrayList
preResult : results) { ArrayList
curResult = new ArrayList
(preResult); curResult.add(nums[i]); tempResults.add(curResult); } results = new ArrayList(tempResults); } return results; }}
View Code

3.subsets-ii(带重复元素的子集)

class Solution {    /**     * @param nums: A set of numbers.     * @return: A list of lists. All valid subsets.     */    public ArrayList
> subsetsWithDup(int[] nums) { // write your code here ArrayList
> results = new ArrayList
>(); if (nums == null) { return results; } if (nums.length == 0) { results.add(new ArrayList
()); return results; } Arrays.sort(nums); helper(results, new ArrayList
(), 0, nums); return results; } private void helper(ArrayList
> results, ArrayList
subset, int startIndex, int[] nums) { results.add(new ArrayList
(subset)); for (int i = startIndex; i < nums.length; i++) { if (i != 0 && nums[i - 1] == nums[i] && i != startIndex) { continue; } subset.add(nums[i]); helper(results, subset, i + 1, nums); subset.remove(subset.size() - 1); } }}
View Code

给定一个可能具有重复数字(这些整数可能重复)的列表,返回其所有可能的子集。子集中的每个元素都是非降序的,两个子集间的顺序是无关紧要的,解集中不能包含重复子集。

思路:解集中不能包含重复的子集,所以使用“选代表法”去重。所以重复的数字都只选择第一个作为代表,例如{1,2(1),2(2)},规定{1,2(1)}和{1, 2(2)}重复。

if (i != 0 && nums[i - 1] == nums[i] && i != startIndex) {     continue;}解释:i != 0 防止数组越界nums[i - 1] == nums[i] && i != startIndex 判断nums[i]前一个跟目前这个是否一致i != startIndex 保证前一个没有被放进list: 如果nums[i - 1] 被放进list,则下一个startIndex是(i+1)也即(i-1+1)=i所以只需判断i != startIndex即可保证前一个没有被放进list
View Code

另一种解法:import java.util.ArrayList;  import java.util.Collections;

class Solution {    /**     * @param nums: A set of numbers.     * @return: A list of lists. All valid subsets.     */    public ArrayList
> subsetsWithDup(int[] nums) { // write your code here ArrayList
> results = new ArrayList
>(); ArrayList
subset = new ArrayList
(); results.add(subset); if (nums == null || nums.length == 0) { return results; } Arrays.sort(nums); for (int i = 0; i < nums.length; i++) { ArrayList
> tempResults = new ArrayList
>(results); for (ArrayList
preResult : results) { ArrayList
curResult = new ArrayList
(preResult); curResult.add(nums[i]); if (!tempResults.contains(curResult)) { tempResults.add(curResult); } } results = new ArrayList(tempResults); } return results; }}
View Code

4.permutations(全排列)

给定一个数字列表,返回其所有可能的排列。你可以假设没有重复数字。

class Solution {    /**     * @param nums: A list of integers.     * @return: A list of permutations.     */    public List
> permute(int[] nums) { // write your code here ArrayList
> results = new ArrayList
>(); if (nums == null) { return results; } if (nums.length == 0) { results.add(new ArrayList
()); return results; } ArrayList
list = new ArrayList
(); helper(results, list, nums); return results; } private void helper(ArrayList
> results, ArrayList
list, int[] nums) { if (list.size() == nums.length) { results.add(new ArrayList
(list)); } for (int i = 0; i < nums.length; i++) { if (list.contains(nums[i])) { continue; } list.add(nums[i]); helper(results, list, nums); list.remove(list.size() - 1); } }}
View Code

注意:无需排序

5.permutations-ii(带重复元素的排列)

给出一个具有重复数字的列表,找出列表所有不同的排列。

class Solution {    /**     * @param nums: A list of integers.     * @return: A list of unique permutations.     */    public List
> permuteUnique(int[] nums) { // Write your code here ArrayList
> results = new ArrayList
>(); if (nums == null) { return results; } if (nums.length == 0) { results.add(new ArrayList
()); return results; } ArrayList
list = new ArrayList
(); Arrays.sort(nums); int[] visited = new int[nums.length]; for (int i = 0; i < nums.length; i++) { visited[i] = 0; } helper(results, list, nums, visited); return results; } private void helper(ArrayList
> results, ArrayList
list, int[] nums, int[] visited) { if (list.size() == nums.length) { results.add(new ArrayList
(list)); } for (int i = 0; i < nums.length; i++) { if ((i != 0 && visited[i - 1] == 0 && nums[i - 1] == nums[i]) || visited[i] == 1) { continue; } visited[i] = 1; list.add(nums[i]); helper(results, list, nums, visited); list.remove(list.size() - 1); visited[i] = 0; } }}
View Code

注意:先排序,使用visited数据记录该数字是否被访问,“选代表法“去重。

if ( visited[i] == 1 || ( i != 0 && nums[i] == nums[i - 1]            && visited[i-1] == 0)){                continue;}上面的判断主要是为了去除重复元素影响。比如,给出一个排好序的数组,[1,2,2],那么第一个2和第二2如果在结果中互换位置, 我们也认为是同一种方案,所以我们强制要求相同的数字,原来排在前面的,在结果 当中也应该排在前面,这样就保证了唯一性。所以当前面的2还没有使用的时候,就不应该让后面的2使用。
View Code

6.hash-function(哈希函数)

在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数。一个好的哈希函数可以尽可能少地产生冲突。一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基于33的一个大整数,比如:

hashcode("abcd") = (ascii(a) * 33的3次方 + ascii(b) * 33的2次方 + ascii(c) *33 + ascii(d)) % HASH_SIZE 

                              = (97* 33的3次方 + 98 * 33的2次方 + 99 * 33 +100) % HASH_SIZE

                              = 3595978 % HASH_SIZE

其中HASH_SIZE表示哈希表的大小(可以假设一个哈希表就是一个索引0 ~ HASH_SIZE-1的数组)。给出一个字符串作为key和一个哈希表的大小,返回这个字符串的哈希值。

class Solution {    /**     * @param key: A String you should hash     * @param HASH_SIZE: An integer     * @return an integer     */    public int hashCode(char[] key, int HASH_SIZE) {        // write your code here        long ans = 0;        for (int i = 0; i < key.length; i++) {            ans = (ans * 33 + (int) key[i]) % HASH_SIZE;        }        return (int) ans;    }};
View Code

7.strstr-ii【Rabin-Karp算法】【hard】

在O(n + m)时间内实现strStr函数。

public class Solution {    /**     * @param source a source string     * @param target a target string     * @return an integer as index     */    public int BASE = 1000000;    public int strStr2(String source, String target) {        // Write your code here        if (source == null || target == null) {            return -1;        }        int m = target.length();        if (m == 0) {            return 0;        }        //31^m        int power = 1;        for (int i = 0; i < m; i++) {            power = (power * 31) % BASE;        }        //targetCode        int targetCode = 0;        for (int i = 0; i < m; i++) {            targetCode = (targetCode * 31 + target.charAt(i)) % BASE;        }        //hashCode        int hashCode = 0;        for (int i = 0; i < source.length(); i++) {            //abc + d            hashCode = (hashCode * 31 + source.charAt(i)) % BASE;            if (i < m - 1) {                continue;            }            //   i            //abcd - a            if (i >= m) {                hashCode = hashCode - (source.charAt(i - m) * power) % BASE;                if (hashCode < 0) {                    hashCode += BASE;                }            }            //double check the string            if (hashCode == targetCode) {                if (source.substring(i - m + 1, i + 1).equals(target)) {                    return i - m + 1;                }            }        }        return -1;    }}
View Code

 

转载于:https://www.cnblogs.com/struggleli/p/6756364.html

你可能感兴趣的文章
错误提示总结
查看>>
实验二+070+胡阳洋
查看>>
Linux IPC实践(3) --具名FIFO
查看>>
Qt之模拟时钟
查看>>
第一次接触安卓--记于2015.8.21
查看>>
(转)在分层架构下寻找java web漏洞
查看>>
mac下多线程实现处理
查看>>
C++ ifstream ofstream
查看>>
跟初学者学习IbatisNet第四篇
查看>>
seL4环境配置
查看>>
Git报错:insufficient permission for adding an object to repository database .git/objects
查看>>
ajax跨域,携带cookie
查看>>
BZOJ 1600: [Usaco2008 Oct]建造栅栏( dp )
查看>>
洛谷 CF937A Olympiad
查看>>
Codeforces Round #445 C. Petya and Catacombs【思维/题意】
查看>>
用MATLAB同时作多幅图
查看>>
python中map的排序以及取出map中取最大最小值
查看>>
ROR 第一章 从零到部署--第一个程序
查看>>
<form>标签
查看>>
vue去掉地址栏# 方法
查看>>