第三周LeetCode算法题两道

第一道

题目名称:46. Permutations

题目难度:Medium

题目描述:Given a collection of distinct numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:

[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

题目分析:
题目的意思就是给你一个没有重复数字的序列,要你找出这个序列中的数字的所有可能的组合情况。

可以非常自然地想到使用递归来解决这个问题。假设序列中数字的个数是n。我们初始的新序列为空。每一层递归遍历所有可以添加进这个新序列的情况。

比如例子中的1 2 3,第一层递归时,将新序列第一位可能的所有情况都遍历到。这样第一层递归之后新序列就有三种情况:[1]、[2]、[3],然后再在给定序列中,删除已经被使用的数字。例子中给定序列是[1,2,3],那么进入第二层的给定序列分别是:[2,3]、[1,3]、[1,2]。
这样,每一层遍历使用给定序列中的一个数,递归结束的条件是给定序列中的数字已经全部被使用。也就是说,给定序列的大小为0。

最后AC的代码如下:

class Solution {
public:
    void nextOne(vector<vector<int> > & result, vector<int> current, vector<int> nums) {
        if (nums.size() == 0) {
            result.push_back(current);
            return;
        }
        for (vector<int>::iterator it = nums.begin(); it!=nums.end(); it++) {
            //新建一个当前未用数字序列的副本以用于之后的恢复
            vector<int> temp(nums);
            //这里重新new一个副本newCur是因为循环的每次都需要对current的序列作操作,但是这些操作又不能相互影响
            vector<int> newCur(current);
            //将一种新的情况添加到当前序列
            newCur.push_back(*it);
            //删除未用序列中刚刚已经被我么使用的数字
            nums.erase(it);
            nextOne(result, newCur, nums);
            //因为删除操作在每次循环中不能相互影响,所以这里要做一个“恢复”的操作
            nums = temp;
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int> > result;
        vector<int> current;
        nextOne(result, current, nums);
        return result;
    }
};

需要特别小心的是,递归时,什么参数可以使用其“引用“,什么参数需要重新建立一个副本。解题过程中题主也在这里掉过一个坑,相关的内容已写在代码注释中。


第二道

题目名称:14. Longest Common Prefix

题目难度:easy

题目描述:Write a function to find the longest common prefix string amongst an array of strings.

题目分析:
这道题要求我们找出所给的一系列字符串中公共的最长的前缀。思路特别简单:
先遍历一遍数组,找出长度最短的字符串。这个字符串最有可能成为“最长的公共前缀“。然后就从头到尾遍历这个候选者包含的字符,对于每一个字符,检查所给的字符串集合中每一个字符串对应的位置的字符是否相同。如果所有字符串对应位置的字符串都与之相同,那末将这个字符加入“结果字符串“result中,然后进入下一位字符的比较。如果不同,则已经找到了最长的公共前缀。

最后AC的代码如下:

class Solution {
public:
    bool common(char c, int index, vector<string>& strs) {
      for (int i = 0; i < strs.size(); i++) {
        if (strs[i][index] != c)
          return false;
      }
      return true;
    }

    string longestCommonPrefix(vector<string>& strs) {
      if(strs.size()==0)
      return "";
      int size = 100000;
      string candidate, result = "";
      for (int i = 0; i < strs.size(); ++i) {
        if (strs[i].size() < size) {
          size = strs[i].size();
          candidate = strs[i];
        }
      }
      for (int i = 0; i < size; i++) {
        if (common(candidate[i], i, strs)) {
          result += candidate[i];
        } else {
          return result;
        }
      }
      return result;
    }
};

需要注意的是测试样例中有空输入的情况,这种情况需要特殊处理。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值