LeetCode143--删除链表的倒数第N个节点、括号生成

1、删除链表的倒数第N个节点(L19)

//给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 
//
// 进阶:你能尝试使用一趟扫描实现吗? 
//
// 
//
// 示例 1: 
//
// 
//输入:head = [1,2,3,4,5], n = 2
//输出:[1,2,3,5]
// 
//
// 示例 2: 
//
// 
//输入:head = [1], n = 1
//输出:[]
// 
//
// 示例 3: 
//
// 
//输入:head = [1,2], n = 1
//输出:[1]
// 
//
// 
//
// 提示: 
//
// 
// 链表中结点的数目为 sz 
// 1 <= sz <= 30 
// 0 <= Node.val <= 100 
// 1 <= n <= sz 
// 
// Related Topics 链表 双指针

我们先求出要删除的这个节点是链表正序第几个节点,然后通过正常删除节点的方式进行删除

public ListNode removeNthFromEnd(ListNode head, int n) {
    	int num = 0;
    	ListNode node1 = head;
		while(node1 != null){
			num++;
			node1 = node1.next;
		}
		//算出这个节点是正序的第几个
		int length = num + 1 - n;
		//如果是第一个,那么直接将头结点删掉
		if(length == 1){
			head = head.next;
			return head;
		}
		//如果不是,直接开始遍历链表,遇到要删除节点的前一个节点就将它的指针指向下下个节点即可
		int k = 0;
		ListNode node2 = head;
		while(node2 != null){
			k++;
			if(k == length - 1){
				node2.next = node2.next.next;
				break;
			}
			node2 = node2.next;
		}
		return head;
    }

2、括号生成(L22)

//数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 
//
// 
//
// 示例 1: 
//
// 
//输入:n = 3
//输出:["((()))","(()())","(())()","()(())","()()()"]
// 
//
// 示例 2: 
//
// 
//输入:n = 1
//输出:["()"]
// 
//
// 
//
// 提示: 
//
// 
// 1 <= n <= 8 
// 
// Related Topics 字符串 回溯算法

有一种方式就是先生成各种括号的组合,不管正反括号的数量是不是一致的,然后将所有产生的这些括号字符串用是否合理来进行判断,只有判断通过的才能放到最后的输出结果中。

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<>();
        generateAll(new char[2*n], 0, list);
        return list;
    }
    private void generateAll(char[] arr, int index, List<String> list){
        if(index == arr.length){
            if(isValid(arr)){
                list.add(new String(arr));
            }
        }else {
            arr[index] = '(';
            generateAll(arr, index+1, list);
            arr[index] = ')';
            generateAll(arr, index+1, list);
        }
    }

    public boolean isValid(char[] current) {
        int balance = 0;
        for (char c: current) {
            if (c == '(') {
                ++balance;
            } else {
                --balance;
            }
            //一旦balance小于0,那么就证明前面出现了过多的‘)’,而在它之前并没有足够的‘(’来进行匹配
            if (balance < 0) {
                return false;
            }
        }
        return balance == 0;
    }
}

还有一种方法是回溯算法,和我们之前做的那个L17基本上是一样的,只不过这里减少了种类,而且增加了条件,所以我们考虑当'('的数量还没有达到n的时候,就可以新增'(',当'('的数量大于')'的时候我们就可以新增')'。

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<>();
        helper(list, "", 0, 0, n);
        return list;
    }
    private void helper(List<String> list, String s, int open, int close, int max){
        if(s.length() == 2*max){
            list.add(s);
        }else{
            if(open < max){
                helper(list, s + '(', open+1, close, max);
            }
            if(open > close){
                helper(list, s + ')', open, close+1, max);
            }
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值