【LeetCode】排序系列

31. Next Permutation

题目:找到给出序列的下一序列。

思路:分三步:一是从后往前找到非递增的位置,即需要开始交换的位置;二是在该位置之后找到第一个比它大的数,并与其交换;三是对后面的序列做一个逆序,然后返回。如果没有找到第一步的位置,就对整个数组逆序。

public class Solution {
    public void nextPermutation(int[] nums) {
        int len = nums.length;
        if(len < 2) return;
        for(int i = len-2; i >= 0; i--){
            if(nums[i+1] > nums[i]){
                for(int j = len-1; j > i; j--){
                    if(nums[j] > nums[i]){
                        int temp = nums[i];
                        nums[i] = nums[j];
                        nums[j] = temp;
                        for(int k = 0; k < (len-1-i)/2; k++){
                            temp = nums[k+i+1];
                            nums[k+i+1] = nums[len-1-k];
                            nums[len-1-k] = temp;
                        }
                        return;
                    }
                }
            }  
        }
        for(int i = 0; i < len/2; i++){
            int temp = nums[i];
            nums[i] = nums[len-1-i];
            nums[len-1-i] = temp;
        }
        return;
    }
}


其他解法类似,只是将反转和交换的过程分开了,反转的过程可以借鉴下,采用两个指针往中间靠近,不容易出错,自己计算次数老出错。


46. Permutations

题目:得到输入数组的所有排列序列。

思路:回溯(递归)——注意要判断list中是否已经包含该数,前提是输入数组每个元素均不相同。注意list也有contains方法。

public class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> ret = new LinkedList<>();
        List<Integer> list = new LinkedList<>();
        backtrack(ret, nums, list, 0);
        return ret;
        
    }
    public void backtrack(List<List<Integer>> ret, int[] nums, List<Integer> list, int x){
        if(x == nums.length){
            ret.add(new LinkedList<Integer>(list));
            return;
        }
        else if(x > nums.length){
            return;
        }
        else{
            for(int i = 0; i < nums.length; i++){
                if(list.contains(nums[i])) continue;
                list.add(nums[i]);
                backtrack(ret, nums, list, x+1);
                list.remove(list.size()-1);
            }
        }
    }
}


改进的做法——在输入的nums做手脚,即打乱nums的顺序,每个交换相邻的位置,然后递归,最后复原。这样大大缩短了时间。

public class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> ret = new LinkedList<>();
        backtrack(ret, nums, 0);
        return ret;
        
    }
    public void backtrack(List<List<Integer>> ret, int[] nums, int x){
        if(x == nums.length){
            List<Integer> list = new LinkedList<>();
            for(int n : nums){
                list.add(n);
            }
            ret.add(list);
            return;
        }
        else if(x > nums.length){
            return;
        }
        else{
            for(int i = x; i < nums.length; i++){
                int temp = nums[i];
                nums[i] = nums[x];
                nums[x] = temp;
                backtrack(ret, nums, x+1);
                nums[x] = nums[i];
                nums[i] = temp;
            }
        }
    }
}


47. Permutations II

题目:数组有重复数时

思路:在40题基础上增加去重的部分,设置flag判断是否跳过重复部分。判断被交换节点和交换节点之间是否有与交换节点相同值的节点,有就跳过。

public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> ret = new LinkedList<>();
        backtrack(ret, nums, 0);
        return ret;
    }
    public void backtrack(List<List<Integer>> ret, int[] nums, int x){
        if(x == nums.length){
            List<Integer> list = new LinkedList<>();
            for(int n : nums){
                list.add(n);
            }
            ret.add(list);
            return;
        }
        else if(x > nums.length){
            return;
        }
        else{
            for(int i = x; i < nums.length; i++){
                boolean flag = true;
                for(int j = x; j < i; j++){
                    if(nums[j] == nums[i]){
                        flag = false;
                        break;
                    }
                }
                if(flag == false) continue;
                int temp = nums[i];
                nums[i] = nums[x];
                nums[x] = temp;
                backtrack(ret, nums, x+1);
                nums[x] = nums[i];
                nums[i] = temp;
            }
        }
    }
}

60. Permutation Sequence

题目:找到全排序列中第k位的序列

思路:从数学的角度来做,按模值分成若干组。新建一个List,每次从中取出一个数加到返回并移除。

public class Solution {
    public String getPermutation(int n, int k) {
        List<Integer> list = new LinkedList<>();
        for(int i = 1; i <= n; i++){
            list.add(i);
        }
        StringBuilder sb = new StringBuilder();
        k--;
        for(int i = n-1; i > 0; i--){
            int jx = jie(i);
            String x = list.get(k/jx).toString();
            sb.append(x);
            list.remove(k/jx);
            k = k%jx;
        }
        sb.append(list.get(0).toString());
        return sb.toString();
    }
    public int jie(int n){
        int ret = 1;
        for(int i = 1; i <= n; i++){
            ret *= i;
        }
        return ret;
    }
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      


深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值