用栈来做是最简便的:
栈(stack)是一种数据结构,遵循先进后出的原则
最常用的方法为stack.pop弹出最顶部的元素并删除
stack.peek弹出最顶部的元素查看,但不删除
stack.push 添加一个元素
代码1,较复杂,但容易理解
public boolean isValid(String s) {
//通过栈来解决
//1.栈用来存放字符串中左括号,当遍历到右括号时,先看栈里是不是空的
//如果栈里是空的,说明没有左括号,或者右括号多出来了
//2.如果栈不是空的,就把栈里元素弹出来与右括号比对,如果匹配,
// 就弹出来并且从栈里删除,这时候一对括号就匹配成功了。如果不匹配,那么也
//返回false
//3.当遍历结束后,栈应该是空的,如果不为空则是左括号多了,因而需要再次判定empty
if (s.isEmpty()) {
return false;
}
Stack<Character> stack = new Stack<>();//加泛型符号
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(' || ch == '[' || ch == '{') {
stack.push(ch);//如果都是左括号,则先入栈
} else {//右括号
if (stack.isEmpty()) {//右括号多了
return false;
}
char top = stack.peek();
if (top == '{' && ch == '}' || top == '(' && ch == ')' || top == '[' && ch == ']') {
stack.pop();//某一对匹配成功
} else {
return false;
}
}
if (!stack.empty()) {
return false;
}
}
return true;
}
思路2,也是通过栈实现,但代码简洁
public boolean isValid1(String s) {
if (s.isEmpty()) {
return false;
}
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(') {//这些if语句让栈里存放与左括号匹配的括号
stack.push(')');
} else if (ch == '[') {
stack.push(']');
} else if (ch == '{') {
stack.push('}');
} else if (stack.isEmpty() || stack.pop() != ch) {
return false;//栈为null说明遇到右括号多出来了;
//或者弹出的元素如果与ch不匹配也返回false
}
}
return stack.isEmpty();//左括号多了则返回false,为null则返回true
}
Leecode题目2
思路:
//遍历l1和l2**
//以l1为核心去求和,遇到10进位1,然后返回链表**
//但会遇到这些情况
//1.链表1比链表2长:下面是以l1为核心遍历,在while语句中加个
// if语句,l2遍历完后为null则停止遍历,只剩下l1继续向后遍历
//2.链表2比链表1长:l2遍历结束后,l1还没结束,将导致提前退出l1的遍历循环,结果不完整
//因而需要加一个if语句,当l1.next为null,但l2不为null时,把l1.next=l2;
//3.解决末尾需要进位的情况,末尾需要进位,但链表已遍历完
//解决方案:在函数位置判断是否大于10的if语句里,去判断l1.next是否为空,如果为空,则给它构造一个新节点
问题1对应的[1,2,3], [1,2]-》》》【2,4,3】
问题2对应的[1,2],[1,5,3]-》》》【2,7,3】
问题3对应的[1,3,9] [3,1,2] ->>>【4,4,1,1】
public ListNode addTwoNumbers(ListNode l1,ListNode l2 ){
ListNode head1=l1;//让head1代替l1去遍历,后面l1在进位时还需遍历
ListNode head2=l2;//直接用l2也可
//遍历并求和
while (head1!=null){
//如果head1不为null则,一直取head1向后遍历
if(head2!=null){
head1.val+=head2.val;
head2=head2.next;
if(head1.next==null&&head2!=null){
head1.next=head2; //该if语句解决上面问题2
break;//**相当于把head2比head1多的部分插到head1后面了
//且head2也不用相加了,因为它本身肯定小于10,所以直接退出循环**
}
}
head1=head1.next;
}
//上面代码实现了两个链表对应每一个节点的求和
//由于链表求和过程中遇到大于等于10的数需要进位,通过定义函数实现
func(l1);//进位操作也是需要遍历一遍,看是否有大于10的数,
// 因而从l1开始,head1此时已经遍历到最后,这也是通过head1记录下来l1节点位置的原因
return l1;
}
public void func(ListNode l1){
while (l1!=null){
if(l1.val>=10){
l1.val=l1.val%10;//得到进位后的值
if(l1.next==null){
l1.next= new ListNode(0);
}//解决问题3
l1.next.val+=1;//给下一节点的值进位
}
l1=l1.next;//继续遍历
}
}
public int halfQuestions(int[] questions) {
int[]arr=new int[1001];//定义一个数组统计包含各种类型的个数
for(int question:questions){
arr[question]++;//数组里对应的是每道题包含的知识点类型
}
//统计好知识点类型
Arrays.sort(arr);//排序好
int count=0;
int n=questions.length/2;
for (int i = arr.length-1; i >=0 ; i--) {
n=n-arr[i];//减去
count++;//每减去一次个数都说明题型+1
if(n<=0){
//说明选择完毕,或者下次溢出
break;
}
}
return count;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)