阿里二面3道算法题

阿里二面3道算法题

今天在一个学习群里看到一个小伙伴去面试了阿里本地生活,二面有4道算法编程题,我们一起来看下难度,我就纳闷了,明明有算法岗,还要求我们这些码农会算法干啥子。毕竟术业有专攻,这是人家的饭碗

1分割平衡字符串

题目描述
在一个「平衡字符串」中,‘L’ 和 ‘R’ 字符的数量是相同的。

给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。

返回可以通过分割得到的平衡字符串的最大数量。

示例 1:

输入:s = “RLRRLLRLRL”
输出:4
解释:s 可以分割为 “RL”, “RRLL”, “RL”, “RL”, 每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’。
示例 2:

输入:s = “RLLLLRRRLR”
输出:3
解释:s 可以分割为 “RL”, “LLLRRR”, “LR”, 每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’。
示例 3:

输入:s = “LLLLRRRR”
输出:1
解释:s 只能保持原样 “LLLLRRRR”.
提示:

1 <= s.length <= 1000
s[i] = ‘L’ 或 ‘R’
分割得到的每个字符串都必须是平衡字符串。
解题思路
遍历字符串,使用一个变量 imbalance 来记录字符串是否达到平衡,遇到’L’,isbalance 加一,遇到’R’,imbalance 减一,当 imbalance 为 0 的时候,这个字符串即为平衡字符串。

复杂度分析
时间复杂度:O(n),其中 n 为字符串 s 的长度。
空间复杂度:O(1)。
代码实现

class Test{
public int balancedStringSplit(String s) {
//输出的总数量
int count= 0;
//是否平衡的标识,为0 时是平衡的
int imbalance = 0;
for (int i = 0; i < s.length(); i ++) {
if (s.charAt(i) == ‘L’) {
isbalance++;
} else {
isbalance–;
}
if (isbalance== 0) {
count++;
}
}
return count;
}
}

2 给出一个数和一个数组,求数组中连续元素的和与给出的数相等的子集合,例如7和int base[] = {1, 4, 2, 3, 4, 3, 6, 7, 8, 9};输出[1,32],[3,4],[4,3],[7]

public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int base[] = {1, 4, 2, 3, 4, 3, 6, 7, 8, 9};
while (true) {
StringBuffer sb = new StringBuffer();
int guest = scanner.nextInt();
int sum = 0;
for (int i = 0; i < base.length; i++) {
List tempBox = new ArrayList<>();
sum = base[i];
tempBox.add(base[i]);
//这个是考虑直接等于7的情况
if (sumguest){
sb.append(tempBox.toString());
continue;
}
for (int j = i+1; j < base.length; j++) {
tempBox.add(base[j]);
//这个是考虑2者相加等于7的情况
sum += base[j];
if (sum
guest) {
sb.append(tempBox.toString());
}
}

        }
        System.out.println(sb.toString());

    }
}

3写一个基于链表的栈

不是有人还不知道栈是什么吧?我用简单的一句话概括下:
吃多了拉就是队列,吃多了吐就是栈,换言之,先进先出的是队列,先进后出的就是栈,这道题重点在于考察链表反转

public class Linked {

private Node<T> first;
private Node<T> tail;

public Linked() {
    first = new Node<T>();
    tail = first;
}

public class Node<T>{
    private Node next;
    private Node pre;
    private T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }
}

public void push(T obj){
    Node<T> node = new Node();
    node.setObj(obj);
    node.pre= tail;
    tail.next =node;
    tail = node;
}

public T pop(){
    if (tail.pre ==null){
        return null;
    }
    T obj = tail.getObj();
    tail = tail.pre;
    tail.next =null;
    return obj;
}

}

测试代码

public void test2(){
    Linked<String> linked = new Linked<>();
    System.out.print("入栈:");
    for (int i =0;i<10;i++){
        linked.push(i+"");
        System.out.print(i+"  ");
    }
    System.out.println();
    System.out.println("出栈");
    for(int i = 0 ;i<10;i++){
        System.out.println(linked.pop());
    }

4 启动3个线程,第一个线程打印0,第二个打印1,第三个打印2,依次类推,打印到20为止

这道题终点在于考察多线程情况下,线程等待和唤醒的时机与对同一个资源加互斥锁
public class TestReentranTLock {
//自己写的demo
int num = -1;
int index = 0;
Lock lock = new ReentrantLock(true);
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
Condition c3 = lock.newCondition();

void thread1(){
	int threadIndex = Integer.parseInt(Thread.currentThread().getName());
	try{
		lock.lock();
		while(threadIndex != index){
			c1.await();
		}
		System.out.print(Thread.currentThread().getName() + " : ");
		System.out.print(++num + ",");
		System.out.println();
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		index = (index + 1) % 3;
		c2.signalAll();
		c3.signalAll();
		lock.unlock();
	}
}
void thread2(){
	int threadIndex = Integer.parseInt(Thread.currentThread().getName());
	try{
		lock.lock();
		while(threadIndex != index){
			c2.await();
		}
		System.out.print(Thread.currentThread().getName() +  " : ");
		System.out.print(++num + ",");
		System.out.println();
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		index = (index + 1) % 3;
		c1.signalAll();
		c3.signalAll();
		lock.unlock();
	}
}
void thread3(){
	int threadIndex = Integer.parseInt(Thread.currentThread().getName());
	try{
		lock.lock();
		while(threadIndex != index){
			c3.await();
		}
		System.out.print(Thread.currentThread().getName() + " : ");
		System.out.print(++num + ",");
		System.out.println();
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		index = (index + 1) % 3;
		c2.signalAll();
		c1.signalAll();
		lock.unlock();
	}
}

public static void main(String[] args) {
	final TestReentranTLock testReentranTLock = new TestReentranTLock();
	new Thread(new Runnable() {
		@Override
		public void run() {
		//考虑到0到20,3个线程只需要循环7次
			for(int j=0;j<7;j++) {
				testReentranTLock.m1();
			}
		}
	}, "1号线程").start();
	new Thread(new Runnable() {
		@Override
		public void run() {
			for(int j=0;j<7;j++) {
				testReentranTLock.m2();
			}
		}
	}, "2号线程").start();
	new Thread(new Runnable() {
		@Override
		public void run() {
			for(int j=0;j<7;j++) {
				testReentranTLock.m3();
			}
		}
	}, "3号线程").start();
}	

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值