40.组合求和II,25.K个一组翻转链表

2 篇文章 0 订阅
1 篇文章 0 订阅

40.组合求和II

1.题目描述

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
①所有数字(包括目标数)都是正整数
②解集不能包含重复的组合。

1.1示例

在这里插入图片描述在这里插入图片描述

2.代码

分析:首先,想到的就是回溯方法。因为考虑到重复的问题,我是使用了set集合来进行去重。接下来就是撸代码了,整体思路还是比较清晰的。实际上代码还需改进。

class Solution {
	//先定义一个结果集
    List<List<Integer>> res;
    //生成一个set进行去重
    Set<List<Integer>> set;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        res=new ArrayList<>();
        set=new HashSet<>();
        //判断candidates非空
        if(candidates==null || candidates.length==0){
            return res;
        }
        int len=candidates.length;
        //排序一下数组
        Arrays.sort(candidates);
        //进行回溯
        traceback(candidates,0,new Stack<Integer>(),target,0);
        //返回结果集
        return res;
    }
    private void traceback(int[] candidates,int start,Stack<Integer> st,int target,int sum){
    	//如果sum==target,说明已经找到了一组数
        if(sum==target){
        	//判断该一组数是否已经存在于res中
            if(!set.contains(new ArrayList(st))){
                set.add(new ArrayList(st));
                res.add(new ArrayList(st));
            }
            return;
        }
        //如果回溯到末尾,或者sum已经大于targe值,可以返回
        if(start==candidates.length || sum>target){
            return;
        }
        //进行遍历
        for(int i=start;i<candidates.length;i++){
            //使用stack结果的st来保存数据
            st.push(candidates[i]);
            sum +=candidates[i];
            //继续回溯
            traceback(candidates,i+1,st,target,sum);
            sum -=candidates[i];
           	//pop出顶层元素
            st.pop();
        }
    }
}

在这里插入图片描述

25.K个一组翻转链表

1.题目描述

给定一个链表,每k个节点一组进行翻转,请你返回翻转后的链表。
k是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是k的整数倍,那么请将最后剩余的节点保持原有顺序。

1.1 示例

在这里插入图片描述
说明:
①你的算法只能使用常数的额外空间。
②你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

2.代码

分析:首先,我们知道需要一个翻转链表的方法。但是这一个链表是有长度要求的,且还需要记录它的首节点和尾结点,所以我们返回一个listNode数组,来记录它的首节点和尾结点。最后,在主代码中分贝指向listNode[0]和listNode[1]即可。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
    	//判断非空性
        if(head==null || head.next==null){
            return head;
        }
        //如果k=1,可以直接返回head
        if(k==1){
            return head;
        }
        //设置一个辅助首节点dummy
        ListNode dummy=new ListNode(0);
        //cur节点表示当前节点
        ListNode cur=head;
        //pre节点表示前一部分链表的尾结点
        ListNode pre=dummy;
        //用来记录当前节点数
        int count=0;
        //first表示需要翻转链表的首节点
        ListNode first=head;
        //tmp节点用来存储后一部分链表的首节点
        ListNode tmp=null;
        while(cur!=null){
            count++;
            //表示已有k个节点,可以进行翻转了
            if(count==k){
            	//存储后一节点
                tmp=cur.next;
                //取出需要当前翻转链表
                cur.next=null;
                //进行翻转
                ListNode[] node=reverse(first);
                //连接前一部分链表
                pre.next=node[0];
                //pre为当前已翻转完成的链表的尾结点
                pre=node[1];
                //重新计数
                count=0;
                //cur为下一部分链表的开始位置
                cur=tmp;
                //存储之后需要翻转的链表的首节点
                first=tmp;
            }else{
                cur=cur.next;
            }
        }
        //连接前后两部分链表
        pre.next=first;
        //返回辅助节点的next节点,就是翻转后链表的首节点
        return dummy.next;
    }
    //返回一个listNode数组,记录翻转后链表的首节点和尾结点。
    private ListNode[] reverse(ListNode head){
    	//判断非空性
        if(head==null || head.next==null){
            return new ListNode[]{null,null};
        }
        ListNode dummy=head;
        ListNode pre=null;
        ListNode cur=head;
        //翻转链表
        while(cur!=null){
            ListNode tmp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=tmp;
        }
        return new ListNode[]{pre,dummy};
    }
}

在这里插入图片描述
第一题链接: https://leetcode-cn.com/problems/combination-sum-ii/.
第二题链接: https://leetcode-cn.com/problems/reverse-nodes-in-k-group/.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值