2022年11月7日算法学习打卡

81 阅读2分钟

day*

上周摆烂了一周

由于后续需要用到Java 因此从今天开始学习使用Java。

基础语法:

  • Java ArrayList

    ArrayList<E> objectName =new ArrayList<>();  // 初始化
      //增:add();
      //删:remove();
      //改:set(2,“wiki”);
      //查:get();
    
    
    

​ 关于Java中函数参数的问题,由于Java中没有指针的概念,因此所有的参数都是采用值传递。

​ ??? 采用值传递的话,Arrays.sort()是如何进行排序的。

216.组合总和III

如果把 组合问题理解了,本题就容易一些了。

题目链接/文章讲解:programmercarl.com/0216.%E7%BB…

思路: 回溯中一道基本的题,在回溯的过程中,通过遍历数组,如果当前和小于目标值,则需要加入新的值,如果大于则需要回退。采用排序来进行剪枝的操作。

代码:

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(candidates);
        backTracking(candidates,new ArrayList<>(),res,target,0 ,0);  
        return res;
    }

    public void backTracking(int[] candidates,List<Integer> path,List<List<Integer>> res,int target,int idx,int sum){

        if(sum == target){
            res.add(new ArrayList<>(path));
            return;
        }

        for(int i = idx;i<candidates.length;i++){
            if(sum+candidates[i]>target) break;
            path.add(candidates[i]);
            backTracking(candidates,path,res,target,i,sum+candidates[i]);
            path.remove(path.size()-1);
        }

    }
}

40.组合总和II

本题开始涉及到一个问题了:去重。

注意题目中给我们 集合是有重复元素的,那么求出来的 组合有可能重复,但题目要求不能有重复组合。

题目链接/文章讲解:programmercarl.com/0040.%E7%BB…

思路: 对于同一层的节点需要进行去重判断,而对于递归向下的则不需要。

代码:

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(candidates);
        backTraversing(res,candidates,new ArrayList<>(),target,0,0);
        return res;

    }

    public void backTraversing(List<List<Integer>> res,int[] candidates,List<Integer> path,int target,int idx,int sum){
        if(sum==target){
           res.add(new ArrayList<>(path));  //与res.add(path)的区别?????
            return;
        }

        for(int i = idx;i<candidates.length;i++){
            if(sum>target) break;           //剪枝操作,避免超时
            if (i > idx && candidates[i] == candidates[i - 1]) {  //i=idx刚到这一层
                continue;
            }
            path.add(candidates[i]);
            backTraversing(res,candidates,path,target,i+1,sum+candidates[i]);  //i+1 避免递归深度中的重复节点
            path.remove(path.size()-1);
        }
    }
}

131.分割回文串

本题较难,大家先看视频来理解 分割问题,明天还会有一道分割问题,先打打基础。

programmercarl.com/0131.%E5%88…

视频讲解:www.bilibili.com/video/BV1c5…

代码:

class Solution {
    List<List<String>> lists = new ArrayList<>();
    Deque<String> deque = new LinkedList<>();

    public List<List<String>> partition(String s) {
        backTracking(s, 0);
        return lists;
    }

    private void backTracking(String s, int startIndex) {
        //如果起始位置大于s的大小,说明找到了一组分割方案
        if (startIndex >= s.length()) {
            lists.add(new ArrayList(deque));
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            //如果是回文子串,则记录
            if (isPalindrome(s, startIndex, i)) {
                String str = s.substring(startIndex, i + 1);
                deque.addLast(str);
            } else {
                continue;
            }
            //起始位置后移,保证不重复
            backTracking(s, i + 1);
            deque.removeLast();
        }
    }
    //判断是否是回文串
    private boolean isPalindrome(String s, int startIndex, int end) {
        for (int i = startIndex, j = end; i < j; i++, j--) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
        }
        return true;
    }
}